Commit 381e2af3 authored by Alvarez, Gonzalo's avatar Alvarez, Gonzalo
Browse files

Ainur: In Complex mode, numbers read as strings

parent d2b600e7
Loading
Loading
Loading
Loading

src/Ainur/AinurComplexHelper.h

deleted100644 → 0
+0 −89
Original line number Diff line number Diff line
#ifndef AINURCOMPLEXHELPER_H
#define AINURCOMPLEXHELPER_H
#include "../Vector.h"

namespace PsimagLite {

template<typename SomeRealType>
class AinurComplexHelper {

public:

	typedef std::complex<SomeRealType> value_type;

	AinurComplexHelper() : t1_(0), t2_(0), counter_(0) {}

	explicit AinurComplexHelper(const SomeRealType& r)
	    : t1_(r), t2_(0), counter_(0) {}

	value_type toComplex() const
	{
		return (counter_ < 2) ? t1_ : value_type(t1_, t2_);
	}

	int end() const { return 0; }

	void insert(int, const SomeRealType& val)
	{
		if (counter_ == 0)
			t1_ = val;
		else if (counter_ == 1)
			t2_ = val;
		if (counter_ > 1)
			err("Wrong complex\n");
		++counter_;
	}

	void insert(int, const value_type& val)
	{
		err("Wrong complex ...\n");
	}

private:

	SomeRealType t1_;
	SomeRealType t2_;
	SizeType counter_;
};

template<typename ComplexOrRealType, bool>
struct MyProxyFor {
	typedef ComplexOrRealType Type;

	static void copy(ComplexOrRealType& dest, const ComplexOrRealType& src)
	{
		dest = src;
	}

	static void copy(std::vector<ComplexOrRealType>& dest,
	                 const std::vector<ComplexOrRealType>& src)
	{
		dest = src;
	}
};

template<typename ComplexOrRealType>
struct MyProxyFor<ComplexOrRealType, true> {

	typedef AinurComplexHelper<typename Real<ComplexOrRealType>::Type> Type;

	static void copy(std::vector<ComplexOrRealType>& dest,
	                 const std::vector<Type>& src)
	{
		dest.clear();
		const SizeType n = src.size();
		if (n == 0) return;
		dest.resize(n);
		for (SizeType i = 0; i < n; ++i)
			dest[i] = src[i].toComplex();
	}

	static void copy(std::vector<ComplexOrRealType>& dest,
	                 const Type& src)
	{
		dest.push_back(src.toComplex());
	}
};

}
#endif // AINURCOMPLEXHELPER_H
+77 −10
Original line number Diff line number Diff line
@@ -4,10 +4,77 @@
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include "AinurDoubleOrFloat.h"
#include "AinurComplexHelper.h"

namespace PsimagLite {

template<typename ComplexOrRealType, bool>
struct MyProxyFor {
	typedef ComplexOrRealType Type;

	static void copy(ComplexOrRealType& dest, const ComplexOrRealType& src)
	{
		dest = src;
	}

	static void copy(std::vector<ComplexOrRealType>& dest,
	                 const std::vector<ComplexOrRealType>& src)
	{
		dest = src;
	}
};

template<typename ComplexOrRealType>
struct MyProxyFor<ComplexOrRealType, true> {

	typedef std::string Type;
	typedef typename Real<ComplexOrRealType>::Type RealType;

	static void copy(std::vector<ComplexOrRealType>& dest,
	                 const std::vector<Type>& src)
	{
		dest.clear();
		const SizeType n = src.size();
		if (n == 0) return;
		dest.resize(n);
		for (SizeType i = 0; i < n; ++i) {
			std::string copystr = src[i];
			dest[i] = toComplex(copystr);
		}
	}

	static void copy(std::vector<ComplexOrRealType>& dest,
	                 const Type& src)
	{
		dest.push_back(toComplex(src));
	}

private:

	static ComplexOrRealType toComplex(std::string str)
	{
		String buffer;
		bool flag = false;
		const SizeType n = str.length();
		RealType real1 = 0;
		for (SizeType i = 0; i < n; ++i) {
			bool isSqrtMinus1 = (str[i] == 'i');
			if (isSqrtMinus1 && flag)
				throw RuntimeError("Error parsing number " + str + "\n");

			if (isSqrtMinus1) {
				flag = true;
				real1 = atof(buffer.c_str());
				buffer = "";
				continue;
			}

			buffer += str[i];
		}

		return ComplexOrRealType(real1, atof(buffer.c_str()));
	}
};

template<typename T>
boost::spirit::qi::rule<std::string::iterator,
std::vector<T>(),
@@ -25,15 +92,15 @@ ruleRows<DoubleOrFloatType>()

template<>
boost::spirit::qi::rule<std::string::iterator,
std::vector<AinurComplexHelper<DoubleOrFloatType> >(),
std::vector<std::string>(),
boost::spirit::qi::space_type>
ruleRows<AinurComplexHelper<DoubleOrFloatType> >()
ruleRows<std::string>()
{
	auto fl = boost::spirit::DoubleOrFloatUnderscore;
	//auto fl = boost::spirit::DoubleOrFloatUnderscore;
	boost::spirit::qi::rule<std::string::iterator,
	std::vector<AinurComplexHelper<DoubleOrFloatType> >(),
	boost::spirit::qi::space_type> myrule =  "[" >> -( ( fl  | "(" >> fl >> "," >> fl >> ")" )
	            % ",") >> "]";
	std::vector<std::string>(),
	boost::spirit::qi::space_type> myrule =  "[" >> (+~boost::spirit::qi::char_(",[]"))
	                                                % ',' >> "]";
	return myrule;
}

@@ -73,13 +140,13 @@ ruleElipsis<DoubleOrFloatType>()

template<>
boost::spirit::qi::rule<std::string::iterator,
AinurComplexHelper<DoubleOrFloatType>(),
std::string(),
boost::spirit::qi::space_type>
ruleElipsis<AinurComplexHelper<DoubleOrFloatType> >()
ruleElipsis<std::string>()
{
	auto fl = boost::spirit::DoubleOrFloatUnderscore;
	boost::spirit::qi::rule<std::string::iterator,
	AinurComplexHelper<DoubleOrFloatType>(),
	std::string(),
	boost::spirit::qi::space_type> myrule =  "[" >> (fl |
	                (fl >> "i" >> fl) |
	                ("i" >> fl))