version 2.19
PIEvaluator setVariable by index bug fix
This commit is contained in:
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
|||||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||||
project(pip)
|
project(pip)
|
||||||
set(pip_MAJOR 2)
|
set(pip_MAJOR 2)
|
||||||
set(pip_MINOR 18)
|
set(pip_MINOR 19)
|
||||||
set(pip_REVISION 0)
|
set(pip_REVISION 0)
|
||||||
set(pip_SUFFIX )
|
set(pip_SUFFIX )
|
||||||
set(pip_COMPANY SHS)
|
set(pip_COMPANY SHS)
|
||||||
|
|||||||
@@ -183,22 +183,77 @@ bool PIEvaluatorContent::setVariableName(int index, const PIString & new_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluatorContent::addFunction(const PIString & name, int args) {
|
||||||
|
functions << PIEvaluatorTypes::Function(name, args, getBaseFunction(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIEvaluatorContent::addVariable(const PIString & name, const complexd & val) {
|
||||||
|
int ind = variables.size_s();
|
||||||
|
variables << PIEvaluatorTypes::Variable(name, val, ind);
|
||||||
|
return ind;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluatorContent::addCustomFunction(const PIString & name, int args_count, FuncFunc func) {
|
||||||
|
functions << PIEvaluatorTypes::Function(name, args_count, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIEvaluatorContent::customVariablesCount() const {
|
||||||
|
return variables.size() - cv_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIEvaluatorContent::findFunction(const PIString & name) const {
|
||||||
|
for (uint i = 0; i < functions.size(); i++)
|
||||||
|
if (functions[i].identifier == name)
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIEvaluatorContent::findVariable(const PIString & var_name) const {
|
||||||
|
for (uint i = 0; i < variables.size(); i++)
|
||||||
|
if (variables[i].name == var_name)
|
||||||
|
return variables[i].index;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIEvaluatorTypes::Function PIEvaluatorContent::function(int index) {
|
||||||
|
if (index < 0 || index >= functions.size_s())
|
||||||
|
return PIEvaluatorTypes::Function();
|
||||||
|
return functions[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIEvaluatorTypes::Variable PIEvaluatorContent::variable(int index) {
|
||||||
|
if (index < 0 || index >= variables.size_s())
|
||||||
|
return PIEvaluatorTypes::Variable();
|
||||||
|
return variables[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIEvaluatorTypes::Variable PIEvaluatorContent::customVariable(int index) {
|
||||||
|
if (index < 0 || index >= variables.size_s() - cv_count)
|
||||||
|
return PIEvaluatorTypes::Variable();
|
||||||
|
return variables[index + cv_count];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluatorContent::removeVariable(int index) {
|
||||||
|
if (index < 0 || index >= variables.size_s()) return;
|
||||||
|
variables.remove(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIEvaluatorContent::clearCustomVariables() {
|
void PIEvaluatorContent::clearCustomVariables() {
|
||||||
variables.clear();
|
variables.clear();
|
||||||
addVariable(PIStringAscii("i" ), complexd_i);
|
addVariable(PIStringAscii("i" ), complexd_i);
|
||||||
addVariable(PIStringAscii("pi"), atan(1.) * 4.);
|
addVariable(PIStringAscii("pi"), atan(1.) * 4.);
|
||||||
addVariable(PIStringAscii("e" ), exp(1.));
|
addVariable(PIStringAscii("e" ), exp(1.));
|
||||||
cv_count = variables.size();
|
cv_count = variables.size_s();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEvaluatorContent::sortVariables() {
|
|
||||||
for (uint i = 0; i < variables.size(); i++) {
|
|
||||||
for (uint j = variables.size() - 1; j > i; j--) {
|
|
||||||
if (variables[j].name.length() <= variables[i].name.length()) continue;
|
|
||||||
piSwap<Variable>(variables[i], variables[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -250,6 +305,16 @@ BaseFunctions PIEvaluatorContent::getBaseFunction(const PIString & name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluatorContent::dump() {
|
||||||
|
for (int i = 0; i < variables.size_s(); ++i) {
|
||||||
|
Variable v(variables[i]);
|
||||||
|
PIString str;
|
||||||
|
//str << "(ind " << v.index << ", mapped " << var_index.value(v.index, -1) << ")";
|
||||||
|
piCout << i << v.name << "=" << v.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const PIString & PIEvaluator::prepare(const PIString & string) {
|
const PIString & PIEvaluator::prepare(const PIString & string) {
|
||||||
currentString = string.trimmed();
|
currentString = string.trimmed();
|
||||||
if (currentString.isEmpty()) currentString = PIStringAscii("0");
|
if (currentString.isEmpty()) currentString = PIStringAscii("0");
|
||||||
@@ -418,15 +483,20 @@ bool PIEvaluator::fillElements() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cnum = 0;
|
cnum = 0;
|
||||||
for (int i = 0; i < content.variablesCount(); i++) {
|
PIMap<int, int> var_index;
|
||||||
curfind = content.variable(i).name;
|
PIVector<PIEvaluatorTypes::Variable> svariables = content.variables;
|
||||||
|
for (int i = 0; i < svariables.size_s(); ++i)
|
||||||
|
svariables[i].index = i;
|
||||||
|
svariables.sort();
|
||||||
|
for (int i = 0; i < svariables.size_s(); i++) {
|
||||||
|
curfind = svariables[i].name;
|
||||||
flen = curfind.length();
|
flen = curfind.length();
|
||||||
fstart = 0;
|
fstart = 0;
|
||||||
while (fstart >= 0) {
|
while (fstart >= 0) {
|
||||||
fstart = tmps.find(curfind, fstart);
|
fstart = tmps.find(curfind, fstart);
|
||||||
if (fstart < 0) break;
|
if (fstart < 0) break;
|
||||||
for (int j = fstart; j < fstart + flen; j++) {
|
for (int j = fstart; j < fstart + flen; j++) {
|
||||||
elements[j].set(etVariable, cnum, i);
|
elements[j].set(etVariable, cnum, svariables[i].index);
|
||||||
tmps.replace(j, 1, fc);
|
tmps.replace(j, 1, fc);
|
||||||
}
|
}
|
||||||
cnum++;
|
cnum++;
|
||||||
@@ -666,7 +736,6 @@ PIString PIEvaluator::preprocess(const PIString & string) {
|
|||||||
variables.push_back(Variable());
|
variables.push_back(Variable());
|
||||||
instructions.push_back(Instruction(oNone, PIVector<short>(1, lind), -variables.size_s()));
|
instructions.push_back(Instruction(oNone, PIVector<short>(1, lind), -variables.size_s()));
|
||||||
}
|
}
|
||||||
kvars = &(content.variables);
|
|
||||||
/*cout << endl << "variables:" << endl;
|
/*cout << endl << "variables:" << endl;
|
||||||
for (int i = 0; i < variables.size(); i++)
|
for (int i = 0; i < variables.size(); i++)
|
||||||
cout << i << " value = " << variables[i].value << endl;
|
cout << i << " value = " << variables[i].value << endl;
|
||||||
@@ -880,7 +949,7 @@ bool PIEvaluator::check() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int j = 0; j < ci.operators.size_s(); j++) {
|
for (int j = 0; j < ci.operators.size_s(); j++) {
|
||||||
if (ci.operators[j] < -variables.size_s() || ci.operators[j] >= kvars->size_s()) {
|
if (ci.operators[j] < -variables.size_s() || ci.operators[j] >= content.variables.size_s()) {
|
||||||
lastError = PIStringAscii("Invalid variable index \"") + PIString::fromNumber(ci.operators[j]) + PIStringAscii("\"");
|
lastError = PIStringAscii("Invalid variable index \"") + PIString::fromNumber(ci.operators[j]) + PIStringAscii("\"");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1111,9 +1180,7 @@ inline void PIEvaluator::execFunction(const Instruction & ci) {
|
|||||||
|
|
||||||
|
|
||||||
inline bool PIEvaluator::execInstructions() {
|
inline bool PIEvaluator::execInstructions() {
|
||||||
kvars = &(content.variables);
|
|
||||||
int oi;
|
int oi;
|
||||||
complexd tmp;
|
|
||||||
tmpvars = variables;
|
tmpvars = variables;
|
||||||
//cout << "var count " << tmpvars.size_s() << endl;
|
//cout << "var count " << tmpvars.size_s() << endl;
|
||||||
for (int i = 0; i < instructions.size_s(); i++) {
|
for (int i = 0; i < instructions.size_s(); i++) {
|
||||||
@@ -1130,11 +1197,11 @@ inline bool PIEvaluator::execInstructions() {
|
|||||||
case oMultiply:
|
case oMultiply:
|
||||||
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[1]);
|
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[1]);
|
||||||
break;
|
break;
|
||||||
case oDivide:
|
case oDivide: {
|
||||||
tmp = value(ci.operators[1]);
|
complexd tmp = value(ci.operators[1]);
|
||||||
if (tmp == complexd(0., 0.)) tmpvars[oi].value = 0.;
|
if (tmp == complexd(0., 0.)) tmpvars[oi].value = 0.;
|
||||||
else tmpvars[oi].value = value(ci.operators[0]) / tmp;
|
else tmpvars[oi].value = value(ci.operators[0]) / tmp;
|
||||||
break;
|
} break;
|
||||||
case oResidue:
|
case oResidue:
|
||||||
tmpvars[oi].value = residue(value(ci.operators[0]), value(ci.operators[1]));
|
tmpvars[oi].value = residue(value(ci.operators[0]), value(ci.operators[1]));
|
||||||
break;
|
break;
|
||||||
@@ -1192,6 +1259,21 @@ bool PIEvaluator::check(const PIString & string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIEvaluator::setVariable(const PIString & name, complexd value) {
|
||||||
|
int ind = content.findVariable(name);
|
||||||
|
if (ind < 0)
|
||||||
|
ind = content.addVariable(name, value);
|
||||||
|
else
|
||||||
|
content.setVariableValue(name, value);
|
||||||
|
return ind;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIEvaluator::setVariable(int index, complexd value) {
|
||||||
|
content.setVariableValue(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
complexd PIEvaluator::evaluate() {
|
complexd PIEvaluator::evaluate() {
|
||||||
if (!execInstructions()) out = 0.;
|
if (!execInstructions()) out = 0.;
|
||||||
if (fabs(out.real()) < 1E-300) out = complexd(0., out.imag());
|
if (fabs(out.real()) < 1E-300) out = complexd(0., out.imag());
|
||||||
|
|||||||
@@ -76,8 +76,9 @@ namespace PIEvaluatorTypes {
|
|||||||
short arguments;
|
short arguments;
|
||||||
};
|
};
|
||||||
struct PIP_EXPORT Variable {
|
struct PIP_EXPORT Variable {
|
||||||
Variable() {value = 0.;}
|
Variable() {value = 0.; index = -1;}
|
||||||
Variable(const PIString & var_name, complexd val) {name = var_name; value = val;}
|
Variable(const PIString & var_name, complexd val, int ind = -1) {name = var_name; value = val; index = ind;}
|
||||||
|
int index;
|
||||||
PIString name;
|
PIString name;
|
||||||
complexd value;
|
complexd value;
|
||||||
};
|
};
|
||||||
@@ -99,29 +100,30 @@ public:
|
|||||||
PIEvaluatorContent();
|
PIEvaluatorContent();
|
||||||
~PIEvaluatorContent() {;}
|
~PIEvaluatorContent() {;}
|
||||||
|
|
||||||
void addFunction(const PIString & name, int args = 1) {functions.push_back(PIEvaluatorTypes::Function(name, args, getBaseFunction(name)));}
|
void addFunction(const PIString & name, int args = 1);
|
||||||
void addVariable(const PIString & name, const complexd & val = 0.) {variables.push_back(PIEvaluatorTypes::Variable(name, val)); sortVariables();}
|
int addVariable(const PIString & name, const complexd & val = 0.);
|
||||||
void addCustomFunction(const PIString & name, int args_count, FuncFunc func) {functions << PIEvaluatorTypes::Function(name, args_count, func);}
|
void addCustomFunction(const PIString & name, int args_count, FuncFunc func);
|
||||||
int functionsCount() const {return functions.size();}
|
int functionsCount() const {return functions.size();}
|
||||||
int variablesCount() const {return variables.size();}
|
int variablesCount() const {return variables.size();}
|
||||||
int customVariablesCount() const {return variables.size() - cv_count;}
|
int customVariablesCount() const;
|
||||||
int findFunction(const PIString & name) const {for (uint i = 0; i < functions.size(); i++) if (functions[i].identifier == name) return i; return -1;}
|
int findFunction(const PIString & name) const;
|
||||||
int findVariable(const PIString & var_name) const {for (uint i = 0; i < variables.size(); i++) if (variables[i].name == var_name) return i; return -1;}
|
int findVariable(const PIString & var_name) const;
|
||||||
PIEvaluatorTypes::Function function(int index) {if (index < 0 || index >= functions.size_s()) return PIEvaluatorTypes::Function(); return functions[index];}
|
PIEvaluatorTypes::Function function(int index);
|
||||||
PIEvaluatorTypes::Variable variable(int index) {if (index < 0 || index >= variables.size_s()) return PIEvaluatorTypes::Variable(); return variables[index];}
|
PIEvaluatorTypes::Variable variable(int index);
|
||||||
PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));}
|
PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));}
|
||||||
PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));}
|
PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));}
|
||||||
PIEvaluatorTypes::Variable customVariable(int index) {if (index < cv_count || index >= variables.size_s() + cv_count) return PIEvaluatorTypes::Variable(); return variables[index + cv_count];}
|
PIEvaluatorTypes::Variable customVariable(int index);
|
||||||
bool setVariableValue(int index, complexd new_value);
|
bool setVariableValue(int index, complexd new_value);
|
||||||
bool setVariableName(int index, const PIString & new_name);
|
|
||||||
bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);}
|
bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);}
|
||||||
|
bool setVariableName(int index, const PIString & new_name);
|
||||||
bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);}
|
bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);}
|
||||||
void removeVariable(int index) {variables.remove(index);}
|
void removeVariable(int index);
|
||||||
void removeVariable(const PIString & var_name) {removeVariable(findVariable(var_name));}
|
void removeVariable(const PIString & var_name) {removeVariable(findVariable(var_name));}
|
||||||
void clearCustomVariables();
|
void clearCustomVariables();
|
||||||
void sortVariables();
|
|
||||||
PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name);
|
PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name);
|
||||||
|
|
||||||
|
void dump();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PIVector<PIEvaluatorTypes::Function> functions;
|
PIVector<PIEvaluatorTypes::Function> functions;
|
||||||
PIVector<PIEvaluatorTypes::Variable> variables;
|
PIVector<PIEvaluatorTypes::Variable> variables;
|
||||||
@@ -154,12 +156,10 @@ public:
|
|||||||
bool isCorrect() const {return correct;}
|
bool isCorrect() const {return correct;}
|
||||||
|
|
||||||
//! Set variable value with name "name" to value "value". Add variable if it doesn`t exists
|
//! Set variable value with name "name" to value "value". Add variable if it doesn`t exists
|
||||||
int setVariable(const PIString & name, complexd value = 0.) {if (content.findVariable(name) < 0) content.addVariable(name, value); else content.setVariableValue(name, value); return content.findVariable(name);}
|
int setVariable(const PIString & name, complexd value = complexd(0.));
|
||||||
|
|
||||||
//! Set variable value with index "index" to value "value". Don`t add variable if it doesn`t exists
|
//! Set variable value with index "index" to value "value". Don`t add variable if it doesn`t exists
|
||||||
void setVariable(int index, complexd value = 0.) {if (index >= 0 && index < content.variablesCount()) content.setVariableValue(index, value);}
|
void setVariable(int index, complexd value = 0.);
|
||||||
|
|
||||||
void setCustomVariableValue(int index, complexd value = 0.) {content.variables[index + content.cv_count].value = value;}
|
|
||||||
|
|
||||||
//! Evaluate last successfully checked with function \a check() expression and returns result
|
//! Evaluate last successfully checked with function \a check() expression and returns result
|
||||||
complexd evaluate();
|
complexd evaluate();
|
||||||
@@ -194,8 +194,6 @@ public:
|
|||||||
//! Restore from %PIByteArray evaluator state (expression, variables, errors, compiled instructions)
|
//! Restore from %PIByteArray evaluator state (expression, variables, errors, compiled instructions)
|
||||||
void load(PIByteArray ba);
|
void load(PIByteArray ba);
|
||||||
|
|
||||||
PIEvaluatorContent content;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const PIString & prepare(const PIString & string);
|
const PIString & prepare(const PIString & string);
|
||||||
PIString preprocess(const PIString & string);
|
PIString preprocess(const PIString & string);
|
||||||
@@ -216,12 +214,13 @@ private:
|
|||||||
PIString inBrackets(const PIString & string);
|
PIString inBrackets(const PIString & string);
|
||||||
PIString operationChar(const PIEvaluatorTypes::Operation & operation);
|
PIString operationChar(const PIEvaluatorTypes::Operation & operation);
|
||||||
void operationsByPriority(int p, PIVector<PIEvaluatorTypes::Operation> & ret);
|
void operationsByPriority(int p, PIVector<PIEvaluatorTypes::Operation> & ret);
|
||||||
complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return kvars->at(index).value;}
|
complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return content.variables[index].value;}
|
||||||
inline complexd residue(const complexd & f, const complexd & s);
|
inline complexd residue(const complexd & f, const complexd & s);
|
||||||
inline void execFunction(const PIEvaluatorTypes::Instruction & ci);
|
inline void execFunction(const PIEvaluatorTypes::Instruction & ci);
|
||||||
|
|
||||||
|
PIEvaluatorContent content;
|
||||||
PIDeque<PIEvaluatorTypes::Element> elements;
|
PIDeque<PIEvaluatorTypes::Element> elements;
|
||||||
PIVector<PIEvaluatorTypes::Variable> currentVariables, variables, tmpvars, * kvars;
|
PIVector<PIEvaluatorTypes::Variable> currentVariables, variables, tmpvars;
|
||||||
PIVector<PIEvaluatorTypes::Instruction> instructions;
|
PIVector<PIEvaluatorTypes::Instruction> instructions;
|
||||||
PIStringList unknownVars, usedVars;
|
PIStringList unknownVars, usedVars;
|
||||||
PIString currentString, lastError;
|
PIString currentString, lastError;
|
||||||
@@ -232,6 +231,8 @@ private:
|
|||||||
|
|
||||||
inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);}
|
inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);}
|
||||||
inline bool operator !=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type != e2.type || e1.num != e2.num);}
|
inline bool operator !=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type != e2.type || e1.num != e2.num);}
|
||||||
|
inline bool operator < (PIEvaluatorTypes::Variable e1, PIEvaluatorTypes::Variable e2) {return e1.name > e2.name;}
|
||||||
|
inline bool operator ==(PIEvaluatorTypes::Variable e1, PIEvaluatorTypes::Variable e2) {return e1.name == e2.name;}
|
||||||
|
|
||||||
inline PIByteArray & operator <<(PIByteArray & s, const PIEvaluatorTypes::Instruction & v) {
|
inline PIByteArray & operator <<(PIByteArray & s, const PIEvaluatorTypes::Instruction & v) {
|
||||||
s << PIByteArray::RawData(&v, sizeof(v) - sizeof(v.operators)) << v.operators;
|
s << PIByteArray::RawData(&v, sizeof(v) - sizeof(v.operators)) << v.operators;
|
||||||
|
|||||||
Reference in New Issue
Block a user