Commit e9e47031 authored by Alvarez, Gonzalo's avatar Alvarez, Gonzalo
Browse files

QuasiCanonical: allow arithmetic of scalars

parent 8426ed8b
......@@ -27,7 +27,7 @@ public:
void plusBackward(T& t2) const
{
t2 += t_;
t2 += t_;
}
void multiply(const AssignAndDestroy& t2)
......@@ -66,7 +66,7 @@ class CanonicalExpression {
typedef typename ItemSpecType::AuxiliaryType AuxiliaryType;
typedef typename Real<ComplexOrRealType>::Type RealType;
typedef Vector<String>::Type VectorStringType;
typedef PsimagLite::QuasiCanonical<ComplexOrRealType> QuasiCanonicalType;
typedef QuasiCanonical<ComplexOrRealType> QuasiCanonicalType;
public:
......@@ -104,6 +104,39 @@ public:
return (ItemSpecType::isEmpty(result)) ? false : true;
}
template<typename T>
static std::pair<bool, String> replaceAll(String str,
String label,
T value)
{
std::pair<bool, String> boolString(true, str);
bool retFlag = false;
while (boolString.first) {
boolString = replaceOne(boolString.second, label, value);
retFlag |= boolString.first;
};
return std::pair<bool, String>(retFlag, boolString.second);
}
template<typename T>
static std::pair<bool, String> replaceOne(String str,
String label,
T value)
{
// find one occurrence
size_t x = str.find(label);
if (x == String::npos) return std::pair<bool, String>(false, str);
String ret = (x == 0) ? "" : str.substr(0, x);
ret += ttos(value);
ret += str.substr(x + label.length(), str.length() - x - label.length());
return std::pair<bool, String>(true, ret);
}
private:
bool procCanonicalTerm(AssignAndDestroyType& assignAndDestroy,
......
......@@ -9,9 +9,131 @@
#include "Stack.h"
#include "../loki/TypeTraits.h"
#include <cmath>
#include "CmplxOrReal.h"
namespace PsimagLite {
template<typename ComplexOrRealType, bool isComplex = IsComplexNumber<ComplexOrRealType>::True>
class IsAnumberPossiblyComplex {};
template<typename ComplexOrRealType>
class IsAnumberPossiblyComplex<ComplexOrRealType, false> {
public:
enum class ComplexParensOrI {PARENS, i}; // , AUTO
IsAnumberPossiblyComplex(String str, ComplexParensOrI = ComplexParensOrI::PARENS)
: flag_(isAfloat(str)), value_(0)
{
if (flag_) value_ = PsimagLite::atof(str.c_str());
}
bool operator()() const { return flag_; }
ComplexOrRealType value() const { return value_; }
private:
bool flag_;
ComplexOrRealType value_;
};
template<typename ComplexOrRealType>
class IsAnumberPossiblyComplex<ComplexOrRealType, true> {
public:
typedef typename Real<ComplexOrRealType>::Type RealType;
typedef Vector<String>::Type VectorStringType;
enum class ComplexParensOrI { PARENS, i}; // , AUTO
IsAnumberPossiblyComplex(String str, ComplexParensOrI mode = ComplexParensOrI::PARENS)
: flag_(false), value_(0)
{
if (mode == ComplexParensOrI::PARENS) {
maybeComplexNumberWithParens(str);
} else {
value_ = strToRealOrImag(str);
flag_ = true;
}
}
bool operator()() const { return flag_; }
ComplexOrRealType value() const { return value_; }
private:
void maybeComplexNumberWithParens(String str)
{
// (a, b) or (a,b)
SizeType l = str.length();
if (l < 5) {
seeIfItsAfloat(str);
return;
}
if (str[0] != '(') {
seeIfItsAfloat(str);
return;
}
String buffer;
String realPart;
String imagPart;
for (SizeType i = 1; i < l; ++i) {
if (str[i] == ',') {
realPart = buffer;
buffer = "";
} else if (str[i] == ')') {
imagPart = buffer;
buffer = "";
} else if (str[i] != ' ') {
buffer += str[i];
} else {
flag_ = false;
return;
}
}
flag_ = (isAfloat(realPart) && isAfloat(imagPart));
if (!flag_) return;
value_ = ComplexOrRealType(PsimagLite::atof(realPart), PsimagLite::atof(imagPart));
}
void seeIfItsAfloat(String str)
{
flag_ = isAfloat(str);
if (!flag_) return;
value_ = PsimagLite::atof(str);
}
static ComplexOrRealType pureRealOrPureImag(String t)
{
static const bool isComplex = IsComplexNumber<ComplexOrRealType>::True;
CpmlxOrReal<RealType, (isComplex) ? 1 : 0> cmplxOrReal(t);
return cmplxOrReal.value();
}
static ComplexOrRealType strToRealOrImag(String content)
{
VectorStringType terms;
split(terms, content, "+");
ComplexOrRealType sum = 0;
const SizeType n = terms.size();
for (SizeType i = 0; i < n; ++i) {
sum += pureRealOrPureImag(terms[i]);
}
return sum;
}
bool flag_;
ComplexOrRealType value_;
};
template<typename ComplexOrRealType>
struct PrepassData {
typedef typename PsimagLite::Vector<ComplexOrRealType>::Type VectorType;
......
......@@ -133,90 +133,6 @@ private:
String microArch_;
};
template<typename ComplexOrRealType, bool isComplex = IsComplexNumber<ComplexOrRealType>::True>
class IsAnumberPossiblyComplex {};
template<typename ComplexOrRealType>
class IsAnumberPossiblyComplex<ComplexOrRealType, false> {
public:
IsAnumberPossiblyComplex(String str)
: flag_(isAfloat(str)), value_(0)
{
if (flag_) value_ = PsimagLite::atof(str.c_str());
}
bool operator()() const { return flag_; }
ComplexOrRealType value() const { return value_; }
private:
bool flag_;
ComplexOrRealType value_;
};
template<typename ComplexOrRealType>
class IsAnumberPossiblyComplex<ComplexOrRealType, true> {
public:
IsAnumberPossiblyComplex(String str)
: flag_(false), value_(0)
{
// (a, b) or (a,b)
SizeType l = str.length();
if (l < 5) {
seeIfItsAfloat(str);
return;
}
if (str[0] != '(') {
seeIfItsAfloat(str);
return;
}
String buffer;
String realPart;
String imagPart;
for (SizeType i = 1; i < l; ++i) {
if (str[i] == ',') {
realPart = buffer;
buffer = "";
} else if (str[i] == ')') {
imagPart = buffer;
buffer = "";
} else if (str[i] != ' ') {
buffer += str[i];
} else {
flag_ = false;
return;
}
}
flag_ = (isAfloat(realPart) && isAfloat(imagPart));
if (!flag_) return;
value_ = ComplexOrRealType(PsimagLite::atof(realPart), PsimagLite::atof(imagPart));
}
bool operator()() const { return flag_; }
ComplexOrRealType value() const { return value_; }
private:
void seeIfItsAfloat(String str)
{
flag_ = isAfloat(str);
if (!flag_) return;
value_ = PsimagLite::atof(str);
}
bool flag_;
ComplexOrRealType value_;
};
} // namespace PsimagLite
void err(PsimagLite::String);
......
......@@ -2,7 +2,7 @@
#define QUASICANONICAL_H
#include "Vector.h"
#include "PsimagLite.h"
#include "CmplxOrReal.h"
#include "ExpressionCalculator.h"
namespace PsimagLite {
......@@ -67,8 +67,9 @@ public:
const SizeType nscalars = ats_.size();
cachedValues_.resize(nscalars);
for (SizeType i = 0; i < nscalars; ++i)
cachedValues_[i] = strToRealOrImag(ats_[i]);
for (SizeType i = 0; i < nscalars; ++i) {
cachedValues_[i] = simpleArithmetics(ats_[i]);
}
}
SizeType numberOfTerms() const { return terms_.size(); }
......@@ -87,7 +88,7 @@ public:
return -1;
String snumber = str.substr(1, len - 2);
SizeType number = PsimagLite::atoi(snumber);
SizeType number = atoi(snumber);
if (number >= ats_.size())
return -1;
return number;
......@@ -139,24 +140,20 @@ public:
private:
static ComplexOrRealType pureRealOrPureImag(String t)
ComplexOrRealType simpleArithmetics(String str)
{
static const bool isComplex = IsComplexNumber<ComplexOrRealType>::True;
CpmlxOrReal<RealType, (isComplex) ? 1 : 0> cmplxOrReal(t);
return cmplxOrReal.value();
}
typedef ExpressionCalculator<ComplexOrRealType> ExpressionCalculatorType;
typedef PrepassData<ComplexOrRealType> PrepassDataType;
static ComplexOrRealType strToRealOrImag(String content)
{
VectorStringType terms;
split(terms, content, "+");
ComplexOrRealType sum = 0;
const SizeType n = terms.size();
for (SizeType i = 0; i < n; ++i) {
sum += pureRealOrPureImag(terms[i]);
}
typename ExpressionCalculatorType::VectorStringType ve;
split(ve, str, ":");
PrepassDataType pd("pi", {M_PI});
ExpressionPrepass<PrepassDataType>::prepass(ve, pd);
return sum;
ExpressionCalculatorType ec(ve);
return ec();
}
String str_;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment