version 2.19

PIEvaluator setVariable by index bug fix
This commit is contained in:
2021-04-01 19:14:54 +03:00
parent 6e4b808a66
commit 58bdcd65a3
3 changed files with 127 additions and 44 deletions

View File

@@ -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() {
variables.clear();
addVariable(PIStringAscii("i" ), complexd_i);
addVariable(PIStringAscii("pi"), atan(1.) * 4.);
addVariable(PIStringAscii("e" ), exp(1.));
cv_count = variables.size();
}
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]);
}
}
cv_count = variables.size_s();
}
@@ -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) {
currentString = string.trimmed();
if (currentString.isEmpty()) currentString = PIStringAscii("0");
@@ -418,15 +483,20 @@ bool PIEvaluator::fillElements() {
}
}
cnum = 0;
for (int i = 0; i < content.variablesCount(); i++) {
curfind = content.variable(i).name;
PIMap<int, int> var_index;
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();
fstart = 0;
while (fstart >= 0) {
fstart = tmps.find(curfind, fstart);
if (fstart < 0) break;
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);
}
cnum++;
@@ -666,7 +736,6 @@ PIString PIEvaluator::preprocess(const PIString & string) {
variables.push_back(Variable());
instructions.push_back(Instruction(oNone, PIVector<short>(1, lind), -variables.size_s()));
}
kvars = &(content.variables);
/*cout << endl << "variables:" << endl;
for (int i = 0; i < variables.size(); i++)
cout << i << " value = " << variables[i].value << endl;
@@ -880,7 +949,7 @@ bool PIEvaluator::check() {
return false;
}
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("\"");
return false;
}
@@ -1111,9 +1180,7 @@ inline void PIEvaluator::execFunction(const Instruction & ci) {
inline bool PIEvaluator::execInstructions() {
kvars = &(content.variables);
int oi;
complexd tmp;
tmpvars = variables;
//cout << "var count " << tmpvars.size_s() << endl;
for (int i = 0; i < instructions.size_s(); i++) {
@@ -1130,11 +1197,11 @@ inline bool PIEvaluator::execInstructions() {
case oMultiply:
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[1]);
break;
case oDivide:
tmp = value(ci.operators[1]);
case oDivide: {
complexd tmp = value(ci.operators[1]);
if (tmp == complexd(0., 0.)) tmpvars[oi].value = 0.;
else tmpvars[oi].value = value(ci.operators[0]) / tmp;
break;
} break;
case oResidue:
tmpvars[oi].value = residue(value(ci.operators[0]), value(ci.operators[1]));
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() {
if (!execInstructions()) out = 0.;
if (fabs(out.real()) < 1E-300) out = complexd(0., out.imag());