diff --git a/main.cpp b/main.cpp index 962b7d6f..52f82e48 100644 --- a/main.cpp +++ b/main.cpp @@ -42,9 +42,9 @@ public: }; int main() { PIEvaluator eval, eval2; - //eval.check("1-1+1"); - //piCout << eval.evaluate().real(); - eval.setVariable("t", complexd(1, 2)); + eval.check("1-1*2"); + piCout << eval.evaluate().real(); + /*eval.setVariable("t", complexd(1, 2)); eval.check("(t*t*(t<8))+(72*(t>8)-8*(9-t)*(9-t)*(t>8)*(t<8.8))+(3*(t-8.8)*(t>8.8))"); PIByteArray ba = eval.save(); piCout << ba.size(); @@ -66,7 +66,7 @@ int main() { e2.setVariable("t", complexd(1, 2)); complexd ret = e2.evaluate(); } - us = tm.elapsed_u(); piCout << " save" << us / 10000.; + us = tm.elapsed_u(); piCout << " save" << us / 10000.;*/ diff --git a/src_main/math/pievaluator.cpp b/src_main/math/pievaluator.cpp index 8c9a081f..87b90783 100755 --- a/src_main/math/pievaluator.cpp +++ b/src_main/math/pievaluator.cpp @@ -118,6 +118,8 @@ * \snippet pievaluator.cpp main */ +using namespace PIEvaluatorTypes; + PIEvaluatorContent::PIEvaluatorContent() { addFunction("arcsin", 1); @@ -193,11 +195,11 @@ void PIEvaluatorContent::clearCustomVariables() { void PIEvaluatorContent::sortVariables() { - //PIEvaluatorTypes::Variable tv; + //Variable tv; 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(variables[i], variables[j]); + piSwap(variables[i], variables[j]); } } /* @@ -209,51 +211,51 @@ void PIEvaluatorContent::sortVariables() { } -PIEvaluatorTypes::BaseFunctions PIEvaluatorContent::getBaseFunction(const PIString & name) { - if (name == "sin") return PIEvaluatorTypes::bfSin; - if (name == "cos") return PIEvaluatorTypes::bfCos; - if (name == "tg") return PIEvaluatorTypes::bfTg; - if (name == "ctg") return PIEvaluatorTypes::bfCtg; - if (name == "arcsin") return PIEvaluatorTypes::bfArcsin; - if (name == "arccos") return PIEvaluatorTypes::bfArccos; - if (name == "arctg") return PIEvaluatorTypes::bfArctg; - if (name == "arcctg") return PIEvaluatorTypes::bfArcctg; - if (name == "exp") return PIEvaluatorTypes::bfExp; - if (name == "random") return PIEvaluatorTypes::bfRandom; - if (name == "randomn") return PIEvaluatorTypes::bfRandomn; - if (name == "sh") return PIEvaluatorTypes::bfSh; - if (name == "ch") return PIEvaluatorTypes::bfCh; - if (name == "th") return PIEvaluatorTypes::bfTh; - if (name == "cth") return PIEvaluatorTypes::bfCth; - if (name == "sqrt") return PIEvaluatorTypes::bfSqrt; - if (name == "sqr") return PIEvaluatorTypes::bfSqr; - if (name == "pow") return PIEvaluatorTypes::bfPow; - if (name == "abs") return PIEvaluatorTypes::bfAbs; - if (name == "ln") return PIEvaluatorTypes::bfLn; - if (name == "lg") return PIEvaluatorTypes::bfLg; - if (name == "log") return PIEvaluatorTypes::bfLog; - if (name == "im") return PIEvaluatorTypes::bfIm; - if (name == "re") return PIEvaluatorTypes::bfRe; - if (name == "arg") return PIEvaluatorTypes::bfArg; - if (name == "len") return PIEvaluatorTypes::bfLen; - if (name == "conj") return PIEvaluatorTypes::bfConj; - if (name == "sign") return PIEvaluatorTypes::bfSign; - if (name == "rad") return PIEvaluatorTypes::bfRad; - if (name == "deg") return PIEvaluatorTypes::bfDeg; - if (name == "j0") return PIEvaluatorTypes::bfJ0; - if (name == "j1") return PIEvaluatorTypes::bfJ1; - if (name == "jn") return PIEvaluatorTypes::bfJN; - if (name == "y0") return PIEvaluatorTypes::bfY0; - if (name == "y1") return PIEvaluatorTypes::bfY1; - if (name == "yn") return PIEvaluatorTypes::bfYN; - if (name == "min") return PIEvaluatorTypes::bfMin; - if (name == "max") return PIEvaluatorTypes::bfMax; - if (name == "clamp") return PIEvaluatorTypes::bfClamp; - if (name == "step") return PIEvaluatorTypes::bfStep; - if (name == "mix") return PIEvaluatorTypes::bfMix; - if (name == "defined") return PIEvaluatorTypes::bfDefined; - if (name == "round") return PIEvaluatorTypes::bfRound; - return PIEvaluatorTypes::bfUnknown; +BaseFunctions PIEvaluatorContent::getBaseFunction(const PIString & name) { + if (name == "sin") return bfSin; + if (name == "cos") return bfCos; + if (name == "tg") return bfTg; + if (name == "ctg") return bfCtg; + if (name == "arcsin") return bfArcsin; + if (name == "arccos") return bfArccos; + if (name == "arctg") return bfArctg; + if (name == "arcctg") return bfArcctg; + if (name == "exp") return bfExp; + if (name == "random") return bfRandom; + if (name == "randomn") return bfRandomn; + if (name == "sh") return bfSh; + if (name == "ch") return bfCh; + if (name == "th") return bfTh; + if (name == "cth") return bfCth; + if (name == "sqrt") return bfSqrt; + if (name == "sqr") return bfSqr; + if (name == "pow") return bfPow; + if (name == "abs") return bfAbs; + if (name == "ln") return bfLn; + if (name == "lg") return bfLg; + if (name == "log") return bfLog; + if (name == "im") return bfIm; + if (name == "re") return bfRe; + if (name == "arg") return bfArg; + if (name == "len") return bfLen; + if (name == "conj") return bfConj; + if (name == "sign") return bfSign; + if (name == "rad") return bfRad; + if (name == "deg") return bfDeg; + if (name == "j0") return bfJ0; + if (name == "j1") return bfJ1; + if (name == "jn") return bfJN; + if (name == "y0") return bfY0; + if (name == "y1") return bfY1; + if (name == "yn") return bfYN; + if (name == "min") return bfMin; + if (name == "max") return bfMax; + if (name == "clamp") return bfClamp; + if (name == "step") return bfStep; + if (name == "mix") return bfMix; + if (name == "defined") return bfDefined; + if (name == "round") return bfRound; + return bfUnknown; } const PIString & PIEvaluator::prepare(const PIString & string) { @@ -396,7 +398,7 @@ bool PIEvaluator::fillElements() { PIString curfind, tmps = currentString; elements.resize(tmps.length()); for (uint i = 0; i < elements.size(); i++) { - elements[i].type = PIEvaluatorTypes::etVariable; + elements[i].type = etVariable; elements[i].var_num = -666; } currentVariables.clear(); @@ -416,7 +418,7 @@ bool PIEvaluator::fillElements() { continue; } for (int j = fstart; j < fstart + flen; j++) { - elements[j].set(PIEvaluatorTypes::etFunction, cnum, cfunc); + elements[j].set(etFunction, cnum, cfunc); tmps.replace(j, 1, fc); } cnum++; @@ -432,7 +434,7 @@ bool PIEvaluator::fillElements() { fstart = tmps.find(curfind, fstart); if (fstart < 0) break; for (int j = fstart; j < fstart + flen; j++) { - elements[j].set(PIEvaluatorTypes::etVariable, cnum, i); + elements[j].set(etVariable, cnum, i); tmps.replace(j, 1, fc); } cnum++; @@ -514,9 +516,9 @@ bool PIEvaluator::fillElements() { } if (numFound) { //qDebug().nospace() << "add " << cnum << ": " << curfind << " = " << curfind.toDouble(); - currentVariables.push_back(PIEvaluatorTypes::Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble())); + currentVariables.push_back(Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble())); for (int j = i - curfind.length(); j < i; j++) { - elements[j].set(PIEvaluatorTypes::etNumber, cnum, -cnum); + elements[j].set(etNumber, cnum, -cnum); tmps.replace(j, 1, fc); } curfind = ""; @@ -527,9 +529,9 @@ bool PIEvaluator::fillElements() { } if (cpart > 0) { //qDebug().nospace() << "add " << cnum << ": " << curfind << " = " << curfind.toDouble(); - currentVariables.push_back(PIEvaluatorTypes::Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble())); + currentVariables.push_back(Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble())); for (int j = tmps.length() - curfind.length(); j < tmps.length(); j++) { - elements[j].set(PIEvaluatorTypes::etNumber, cnum, -cnum); + elements[j].set(etNumber, cnum, -cnum); tmps.replace(j, 1, fc); } } @@ -542,17 +544,17 @@ bool PIEvaluator::fillElements() { if (i < tmps.length() - 1) nc = tmps[i + 1]; else nc = fc; if (cc == '(' || cc == ')' || cc == ',') { - elements[i].set(PIEvaluatorTypes::etOperator, -1); + elements[i].set(etOperator, -1); continue; } if (cc == '-' || cc == '+') { - elements[i].set(PIEvaluatorTypes::etOperator, -1); - if (i < tmps.length() - 1) if (elements[i + 1].type == PIEvaluatorTypes::etVariable || - elements[i + 1].type == PIEvaluatorTypes::etFunction) continue; + elements[i].set(etOperator, -1); + if (i < tmps.length() - 1) if (elements[i + 1].type == etVariable || + elements[i + 1].type == etFunction) continue; if ((pc == '(' || isSign(pc) || i == 0) && i < tmps.length() - 1) { - if (elements[i + 1].type != PIEvaluatorTypes::etOperator) { + if (elements[i + 1].type != etOperator) { cnum = elements[i + 1].num; - elements[i].set(PIEvaluatorTypes::etNumber, cnum); + elements[i].set(etNumber, cnum); tmps.replace(i, 1, fc); ///cout << "found sign " << cc << " :" << cnum - 1 << endl; if (cc == '-' && currentVariables.size_s() >= cnum) @@ -563,7 +565,7 @@ bool PIEvaluator::fillElements() { } } if (isSign(cc)) { - elements[i].set(PIEvaluatorTypes::etOperator, -1); + elements[i].set(etOperator, -1); continue; } } @@ -598,20 +600,20 @@ bool PIEvaluator::setSignes() { pc = tmps[pi].toLower(); //if (elements[i].type == etOperator || elements[ni].type == etVariable) continue; if (fc == ',' || sc == ',') continue; - if (elements[i].type == PIEvaluatorTypes::etOperator && elements[ni].type == PIEvaluatorTypes::etOperator) continue; - if (fc == ')' && (elements[ni].type == PIEvaluatorTypes::etNumber || elements[ni].type == PIEvaluatorTypes::etVariable || elements[ni].type == PIEvaluatorTypes::etFunction)) needInsert = 1; - if (sc == '(' && (elements[i].type == PIEvaluatorTypes::etNumber || elements[i].type == PIEvaluatorTypes::etVariable)) needInsert = 1; - if (elements[i].type == PIEvaluatorTypes::etNumber && elements[ni].type == PIEvaluatorTypes::etNumber && elements[i].num != elements[ni].num) needInsert = 1; - if (elements[i].type == PIEvaluatorTypes::etVariable && elements[ni].type == PIEvaluatorTypes::etVariable && elements[i].num != elements[ni].num) needInsert = 1; - if ((elements[i].type == PIEvaluatorTypes::etNumber && elements[ni].type == PIEvaluatorTypes::etVariable) || (elements[i].type == PIEvaluatorTypes::etVariable && elements[ni].type == PIEvaluatorTypes::etNumber)) needInsert = 1; - if ((elements[i].type == PIEvaluatorTypes::etNumber || elements[i].type == PIEvaluatorTypes::etVariable) && elements[ni].type == PIEvaluatorTypes::etFunction) needInsert = 1; - if (elements[i].type == PIEvaluatorTypes::etFunction && elements[ni].type == PIEvaluatorTypes::etFunction && elements[i].num != elements[ni].num) needInsert = 2; - if (elements[i].type == PIEvaluatorTypes::etFunction && elements[ni].type != PIEvaluatorTypes::etFunction && sc != '(') needInsert = 2; - if (elements[pi].type == PIEvaluatorTypes::etOperator && (elements[ni].type == PIEvaluatorTypes::etFunction || elements[ni].type == PIEvaluatorTypes::etVariable) && fc == '-') needInsert = 3; + if (elements[i].type == etOperator && elements[ni].type == etOperator) continue; + if (fc == ')' && (elements[ni].type == etNumber || elements[ni].type == etVariable || elements[ni].type == etFunction)) needInsert = 1; + if (sc == '(' && (elements[i].type == etNumber || elements[i].type == etVariable)) needInsert = 1; + if (elements[i].type == etNumber && elements[ni].type == etNumber && elements[i].num != elements[ni].num) needInsert = 1; + if (elements[i].type == etVariable && elements[ni].type == etVariable && elements[i].num != elements[ni].num) needInsert = 1; + if ((elements[i].type == etNumber && elements[ni].type == etVariable) || (elements[i].type == etVariable && elements[ni].type == etNumber)) needInsert = 1; + if ((elements[i].type == etNumber || elements[i].type == etVariable) && elements[ni].type == etFunction) needInsert = 1; + if (elements[i].type == etFunction && elements[ni].type == etFunction && elements[i].num != elements[ni].num) needInsert = 2; + if (elements[i].type == etFunction && elements[ni].type != etFunction && sc != '(') needInsert = 2; + if (elements[pi].type == etOperator && (elements[ni].type == etFunction || elements[ni].type == etVariable) && fc == '-') needInsert = 3; switch (needInsert) { case 1: currentString.insert(ni + inserted, "*"); - elements.insert(ni + inserted, PIEvaluatorTypes::Element(PIEvaluatorTypes::etOperator, -1)); + elements.insert(ni + inserted, Element(etOperator, -1)); //inserted++; //i++; return true; @@ -625,7 +627,7 @@ bool PIEvaluator::setSignes() { return true;*/ case 3: currentString.insert(ni + inserted, "1*"); - elements.insert(ni + inserted, PIEvaluatorTypes::Element(PIEvaluatorTypes::etOperator, -1)); + elements.insert(ni + inserted, Element(etOperator, -1)); //inserted; //i++; return true; @@ -644,10 +646,10 @@ bool PIEvaluator::setSignes() { void PIEvaluator::convert() { int j; - PIEvaluatorTypes::Element ce, pe; + Element ce, pe; for (int i = 0; i < currentString.length(); i++) { pe = elements[i]; - if (pe.type != PIEvaluatorTypes::etFunction) continue; + if (pe.type != etFunction) continue; j = i + 1; while (j < currentString.length()) { ce = elements[j]; @@ -660,7 +662,7 @@ void PIEvaluator::convert() { } for (int i = 0; i < currentString.length(); i++) { pe = elements[i]; - if (pe.type != PIEvaluatorTypes::etNumber) continue; + if (pe.type != etNumber) continue; j = i + 1; while (j < currentString.length()) { ce = elements[j]; @@ -673,7 +675,7 @@ void PIEvaluator::convert() { } for (int i = 0; i < currentString.length(); i++) { pe = elements[i]; - if (pe.type != PIEvaluatorTypes::etVariable) continue; + if (pe.type != etVariable) continue; j = i + 1; while (j < currentString.length()) { ce = elements[j]; @@ -709,8 +711,8 @@ PIString PIEvaluator::preprocess(const PIString & string) { variables = currentVariables; lind = parse(currentString); if (instructions.size() == 0) { - variables.push_back(PIEvaluatorTypes::Variable()); - instructions.push_back(PIEvaluatorTypes::Instruction(PIEvaluatorTypes::oNone, PIVector(1, lind), -variables.size_s())); + variables.push_back(Variable()); + instructions.push_back(Instruction(oNone, PIVector(1, lind), -variables.size_s())); } kvars = &(content.variables); /* @@ -734,36 +736,14 @@ PIString PIEvaluator::preprocess(const PIString & string) { } -PIEvaluatorTypes::Operation PIEvaluator::operationInOrder(const int & index) { - switch (index) { - case 0: return PIEvaluatorTypes::oPower; - case 1: return PIEvaluatorTypes::oMultiply; - case 2: return PIEvaluatorTypes::oDivide; - case 3: return PIEvaluatorTypes::oResidue; - case 4: return PIEvaluatorTypes::oAdd; - case 5: return PIEvaluatorTypes::oSubtract; - case 6: return PIEvaluatorTypes::oEqual; - case 7: return PIEvaluatorTypes::oNotEqual; - case 8: return PIEvaluatorTypes::oGreaterEqual; - case 9: return PIEvaluatorTypes::oSmallerEqual; - case 10: return PIEvaluatorTypes::oGreater; - case 11: return PIEvaluatorTypes::oSmaller; - case 12: return PIEvaluatorTypes::oAnd; - case 13: return PIEvaluatorTypes::oOr; - default: return PIEvaluatorTypes::oNone; - } -} - - int PIEvaluator::parse(const PIString & string, int offset) { int slen = string.length(), /*facnt,*/ farg, bcnt, k; PIChar cc; - PIEvaluatorTypes::Element ce; - PIEvaluatorTypes::Function cfunc; - PIEvaluatorTypes::Operation coper; + Element ce; + Function cfunc; PIString sbrackets, carg; PIVector args, atmp; - PIVector opers; + PIVector opers; ///qDebug() << "to parse :" + string; ///cout << " "; for (int i = 0; i < slen; i++) cout << preproc->elements[i + offset].type; cout << endl; @@ -772,13 +752,13 @@ int PIEvaluator::parse(const PIString & string, int offset) { ce = elements[i + offset]; cc = string[i]; switch (ce.type) { - case PIEvaluatorTypes::etNumber: + case etNumber: args.push_back(ce.var_num); continue; - case PIEvaluatorTypes::etVariable: + case etVariable: args.push_back(ce.var_num); continue; - case PIEvaluatorTypes::etFunction: + case etFunction: i++; cfunc = content.function(ce.var_num); //facnt = cfunc.arguments; @@ -821,15 +801,15 @@ int PIEvaluator::parse(const PIString & string, int offset) { } i = k - 1; if (farg > 0) { - variables.push_back(PIEvaluatorTypes::Variable()); + variables.push_back(Variable()); farg = -variables.size_s(); } - instructions.push_back(PIEvaluatorTypes::Instruction(PIEvaluatorTypes::oFunction, atmp, farg, ce.var_num)); + instructions.push_back(Instruction(oFunction, atmp, farg, ce.var_num)); args.push_back(farg); //for (int i = 0; i < args.size_s(); i++) cout << preproc->currentVariables[-args[i]].value << endl; //i = j + 1; continue; - case PIEvaluatorTypes::etOperator: + case etOperator: //qDebug() << "operator: " << cc; if (cc == '(') { sbrackets = inBrackets(string.right(slen - i)); @@ -837,20 +817,20 @@ int PIEvaluator::parse(const PIString & string, int offset) { i += sbrackets.length() + 1; continue; } - if (cc == '+') {opers.push_back(PIEvaluatorTypes::oAdd); continue;} - if (cc == '-') {opers.push_back(PIEvaluatorTypes::oSubtract); continue;} - if (cc == '*') {opers.push_back(PIEvaluatorTypes::oMultiply); continue;} - if (cc == '/') {opers.push_back(PIEvaluatorTypes::oDivide); continue;} - if (cc == '%') {opers.push_back(PIEvaluatorTypes::oResidue); continue;} - if (cc == '^') {opers.push_back(PIEvaluatorTypes::oPower); continue;} - if (cc == '=') {opers.push_back(PIEvaluatorTypes::oEqual); continue;} - if (cc == ':') {opers.push_back(PIEvaluatorTypes::oNotEqual); continue;} - if (cc == '}') {opers.push_back(PIEvaluatorTypes::oGreaterEqual); continue;} - if (cc == '{') {opers.push_back(PIEvaluatorTypes::oSmallerEqual); continue;} - if (cc == '>') {opers.push_back(PIEvaluatorTypes::oGreater); continue;} - if (cc == '<') {opers.push_back(PIEvaluatorTypes::oSmaller); continue;} - if (cc == '&') {opers.push_back(PIEvaluatorTypes::oAnd); continue;} - if (cc == '|') {opers.push_back(PIEvaluatorTypes::oOr); continue;} + if (cc == '+') {opers.push_back(oAdd); continue;} + if (cc == '-') {opers.push_back(oSubtract); continue;} + if (cc == '*') {opers.push_back(oMultiply); continue;} + if (cc == '/') {opers.push_back(oDivide); continue;} + if (cc == '%') {opers.push_back(oResidue); continue;} + if (cc == '^') {opers.push_back(oPower); continue;} + if (cc == '=') {opers.push_back(oEqual); continue;} + if (cc == ':') {opers.push_back(oNotEqual); continue;} + if (cc == '}') {opers.push_back(oGreaterEqual); continue;} + if (cc == '{') {opers.push_back(oSmallerEqual); continue;} + if (cc == '>') {opers.push_back(oGreater); continue;} + if (cc == '<') {opers.push_back(oSmaller); continue;} + if (cc == '&') {opers.push_back(oAnd); continue;} + if (cc == '|') {opers.push_back(oOr); continue;} } } /* @@ -863,14 +843,14 @@ int PIEvaluator::parse(const PIString & string, int offset) { if (args.size_s() > 0) return args.back(); else return -666; } - for (int i = 0; i < PIEvaluatorTypes::oOperatorsCount; i++) { - coper = operationInOrder(i); + + int oprior = -1; + PIVector opv; + for (;;) { + operationsByPriority(++oprior, opv); + if (opv.isEmpty()) break; for (int j = 0; j < opers.size_s(); j++) { - if (coper == PIEvaluatorTypes::oDivide || coper == PIEvaluatorTypes::oMultiply) { - if (opers[j] != PIEvaluatorTypes::oDivide && opers[j] != PIEvaluatorTypes::oMultiply) continue; - } else { - if (opers[j] != coper) continue; - } + if (!opv.contains(opers[j])) continue; atmp.clear(); if (j < args.size_s() && j >= 0) atmp.push_back(args[j]); else atmp.push_back(-666); @@ -881,11 +861,11 @@ int PIEvaluator::parse(const PIString & string, int offset) { else { if (atmp[1] < 0) farg = atmp[1]; else { - variables.push_back(PIEvaluatorTypes::Variable()); + variables.push_back(Variable()); farg = -variables.size_s(); } } - instructions.push_back(PIEvaluatorTypes::Instruction(opers[j], atmp, farg)); + instructions.push_back(Instruction(opers[j], atmp, farg)); if (j >= 0 && j < args.size_s()) { args.remove(j); if (j < args.size_s()) args[j] = farg; @@ -900,7 +880,7 @@ int PIEvaluator::parse(const PIString & string, int offset) { bool PIEvaluator::check() { - PIEvaluatorTypes::Instruction ci; + Instruction ci; bool error; if (unknownVars.size_s() > 0) { lastError = "Unknown variables: \"" + unknownVars.join("\", \"") + "\""; @@ -909,11 +889,11 @@ bool PIEvaluator::check() { for (int i = 0; i < instructions.size_s(); i++) { error = false; ci = instructions[i]; - PIEvaluatorTypes::Function cf; + Function cf; int fac, gac; switch (ci.operation) { - case PIEvaluatorTypes::oNone: break; - case PIEvaluatorTypes::oFunction: + case oNone: break; + case oFunction: cf = content.function(ci.function); fac = cf.arguments; gac = ci.operators.size_s(); @@ -986,27 +966,41 @@ PIString PIEvaluator::inBrackets(const PIString & string) { } -PIString PIEvaluator::operationChar(const PIEvaluatorTypes::Operation & operation) { +PIString PIEvaluator::operationChar(const Operation & operation) { switch (operation) { - case PIEvaluatorTypes::oAdd: return "+"; - case PIEvaluatorTypes::oSubtract: return "-"; - case PIEvaluatorTypes::oMultiply: return "*"; - case PIEvaluatorTypes::oDivide: return "/"; - case PIEvaluatorTypes::oPower: return "^"; - case PIEvaluatorTypes::oResidue: return "%"; - case PIEvaluatorTypes::oEqual: return "="; - case PIEvaluatorTypes::oNotEqual: return PIString::fromUTF8("≠"); - case PIEvaluatorTypes::oGreaterEqual: return PIString::fromUTF8("≥"); - case PIEvaluatorTypes::oSmallerEqual: return PIString::fromUTF8("≤"); - case PIEvaluatorTypes::oGreater: return ">"; - case PIEvaluatorTypes::oSmaller: return "<"; - case PIEvaluatorTypes::oAnd: return PIString::fromUTF8("⋀"); - case PIEvaluatorTypes::oOr: return PIString::fromUTF8("⋁"); + case oAdd: return "+"; + case oSubtract: return "-"; + case oMultiply: return "*"; + case oDivide: return "/"; + case oPower: return "^"; + case oResidue: return "%"; + case oEqual: return "="; + case oNotEqual: return PIString::fromUTF8("≠"); + case oGreaterEqual: return PIString::fromUTF8("≥"); + case oSmallerEqual: return PIString::fromUTF8("≤"); + case oGreater: return ">"; + case oSmaller: return "<"; + case oAnd: return PIString::fromUTF8("⋀"); + case oOr: return PIString::fromUTF8("⋁"); default: return "???"; } } +void PIEvaluator::operationsByPriority(int p, PIVector & ret) { + ret.clear(); + switch (p) { + case 0: ret << oPower; break; + case 1: ret << oMultiply << oDivide << oResidue; break; + case 2: ret << oAdd << oSubtract; break; + case 3: ret << oEqual << oNotEqual << oGreaterEqual << oSmallerEqual << oGreater << oSmaller; break; + case 4: ret << oAnd; break; + case 5: ret << oOr; break; + default: break; + } +} + + inline complexd PIEvaluator::residue(const complexd & f, const complexd & s) { complexd ret; if (s.real() != 0.) ret = complexd(f.real() - ((int)(f.real() / s.real())) * s.real(), 0.); @@ -1015,123 +1009,123 @@ inline complexd PIEvaluator::residue(const complexd & f, const complexd & s) { } -inline void PIEvaluator::execFunction(const PIEvaluatorTypes::Instruction & ci) { - const PIEvaluatorTypes::Function & cfunc(content.function(ci.function)); +inline void PIEvaluator::execFunction(const Instruction & ci) { + const Function & cfunc(content.function(ci.function)); int oi = -ci.out - 1; complexd tmp, stmp, ttmp; //qDebug() << "function " << (int)cfunc.type; switch (cfunc.type) { - case PIEvaluatorTypes::bfSin: + case bfSin: tmpvars[oi].value = sin(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfCos: + case bfCos: tmpvars[oi].value = cos(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfTg: + case bfTg: tmpvars[oi].value = tan(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfCtg: + case bfCtg: tmp = tan(value(ci.operators[0])); if (tmp == complexd_0) tmpvars[oi].value = 0.; else tmpvars[oi].value = complexd_1 / tmp; break; - case PIEvaluatorTypes::bfArcsin: + case bfArcsin: tmpvars[oi].value = asinc(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfArccos: + case bfArccos: tmpvars[oi].value = acosc(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfArctg: + case bfArctg: tmpvars[oi].value = atanc(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfArcctg: + case bfArcctg: tmp = atanc(value(ci.operators[0])); if (tmp == complexd_0) tmpvars[oi].value = 0.; else tmpvars[oi].value = complexd_1 / tmp; break; - case PIEvaluatorTypes::bfSh: + case bfSh: tmpvars[oi].value = sinh(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfCh: + case bfCh: tmpvars[oi].value = cosh(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfTh: + case bfTh: tmpvars[oi].value = tanh(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfCth: + case bfCth: tmp = tanh(value(ci.operators[0])); if (tmp == complexd_0) tmpvars[oi].value = 0.; else tmpvars[oi].value = complexd_1 / tmp; break; - case PIEvaluatorTypes::bfAbs: + case bfAbs: tmpvars[oi].value = abs(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfSqrt: + case bfSqrt: tmpvars[oi].value = sqrt(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfSqr: + case bfSqr: tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[0]); break; - case PIEvaluatorTypes::bfExp: + case bfExp: tmpvars[oi].value = exp(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfPow: + case bfPow: tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1])); break; - case PIEvaluatorTypes::bfLn: + case bfLn: tmpvars[oi].value = log(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfLg: + case bfLg: tmpvars[oi].value = log10(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfLog: + case bfLog: tmp = log(value(ci.operators[1])); if (tmp == complexd_0) tmpvars[oi].value = 0.; else tmpvars[oi].value = log(value(ci.operators[0])) / tmp; break; - case PIEvaluatorTypes::bfRe: + case bfRe: tmpvars[oi].value = value(ci.operators[0]).real(); break; - case PIEvaluatorTypes::bfIm: + case bfIm: tmpvars[oi].value = value(ci.operators[0]).imag(); break; - case PIEvaluatorTypes::bfArg: + case bfArg: tmpvars[oi].value = arg(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfLen: + case bfLen: tmpvars[oi].value = abs(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfConj: + case bfConj: tmpvars[oi].value = conj(value(ci.operators[0])); break; - case PIEvaluatorTypes::bfSign: + case bfSign: tmpvars[oi].value = value(ci.operators[0]).real() >= 0. ? complexd_1 : -complexd_1; break; - case PIEvaluatorTypes::bfRad: + case bfRad: tmpvars[oi].value = value(ci.operators[0]) * complexd(deg2rad, 0.); break; - case PIEvaluatorTypes::bfDeg: + case bfDeg: tmpvars[oi].value = value(ci.operators[0]) * complexd(rad2deg, 0.); break; - case PIEvaluatorTypes::bfJ0: + case bfJ0: tmpvars[oi].value = piJ0(value(ci.operators[0]).real()); break; - case PIEvaluatorTypes::bfJ1: + case bfJ1: tmpvars[oi].value = piJ1(value(ci.operators[0]).real()); break; - case PIEvaluatorTypes::bfJN: + case bfJN: tmpvars[oi].value = piJn(piRoundd(value(ci.operators[1]).real()), value(ci.operators[0]).real()); break; - case PIEvaluatorTypes::bfY0: + case bfY0: tmpvars[oi].value = piY0(value(ci.operators[0]).real()); break; - case PIEvaluatorTypes::bfY1: + case bfY1: tmpvars[oi].value = piY1(value(ci.operators[0]).real()); break; - case PIEvaluatorTypes::bfYN: + case bfYN: tmpvars[oi].value = piYn(piRoundd(value(ci.operators[1]).real()), value(ci.operators[0]).real()); break; - case PIEvaluatorTypes::bfMin: + case bfMin: tmp = value(ci.operators[0]); for (int i = 1; i < ci.operators.size_s(); ++i) { stmp = value(ci.operators[i]); @@ -1139,7 +1133,7 @@ inline void PIEvaluator::execFunction(const PIEvaluatorTypes::Instruction & ci) } tmpvars[oi].value = tmp; break; - case PIEvaluatorTypes::bfMax: + case bfMax: tmp = value(ci.operators[0]); for (int i = 1; i < ci.operators.size_s(); ++i) { stmp = value(ci.operators[i]); @@ -1147,31 +1141,31 @@ inline void PIEvaluator::execFunction(const PIEvaluatorTypes::Instruction & ci) } tmpvars[oi].value = tmp; break; - case PIEvaluatorTypes::bfClamp: - tmp = value(ci.operators[0]); + case bfClamp: + tmp = value(ci.operators[0]); stmp = value(ci.operators[1]); ttmp = value(ci.operators[2]); tmpvars[oi].value = complexd(piClampd(tmp.real(), stmp.real(), ttmp.real()), piClampd(tmp.imag(), stmp.imag(), ttmp.imag())); break; - case PIEvaluatorTypes::bfStep: + case bfStep: tmpvars[oi].value = complexd(value(ci.operators[0]).real() >= value(ci.operators[1]).real() ? complexld_1 : complexld_0); break; - case PIEvaluatorTypes::bfMix: - tmp = value(ci.operators[0]); + case bfMix: + tmp = value(ci.operators[0]); stmp = value(ci.operators[1]); ttmp = value(ci.operators[2]); tmpvars[oi].value = stmp.real() * (1. - tmp.real()) + ttmp.real() * tmp.real(); break; - case PIEvaluatorTypes::bfDefined: + case bfDefined: tmpvars[oi].value = value(ci.operators[0]).real() > 0. ? complexd_1 : complexd_0; break; - case PIEvaluatorTypes::bfRandom: + case bfRandom: tmpvars[oi].value = value(ci.operators[0]) + randomd() * value(ci.operators[1]); break; - case PIEvaluatorTypes::bfRandomn: + case bfRandomn: tmpvars[oi].value = randomn(value(ci.operators[0]).real(), value(ci.operators[1]).real()); break; - case PIEvaluatorTypes::bfRound: + case bfRound: tmpvars[oi].value = piRoundd(value(ci.operators[0]).real()); break; default: break; @@ -1186,58 +1180,58 @@ inline bool PIEvaluator::execInstructions() { tmpvars = variables; //cout << "var count " << tmpvars.size_s() << endl; for (int i = 0; i < instructions.size_s(); i++) { - const PIEvaluatorTypes::Instruction & ci(instructions[i]); + const Instruction & ci(instructions[i]); oi = -ci.out - 1; //cout << value(ci.operators[0]) << operationChar(ci.operation) << value(ci.operators[1]) << ", " << oi << endl; switch (ci.operation) { - case PIEvaluatorTypes::oAdd: + case oAdd: tmpvars[oi].value = value(ci.operators[0]) + value(ci.operators[1]); break; - case PIEvaluatorTypes::oSubtract: + case oSubtract: tmpvars[oi].value = value(ci.operators[0]) - value(ci.operators[1]); break; - case PIEvaluatorTypes::oMultiply: + case oMultiply: tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[1]); break; - case PIEvaluatorTypes::oDivide: + case oDivide: tmp = value(ci.operators[1]); if (tmp == complexd(0., 0.)) tmpvars[oi].value = 0.; else tmpvars[oi].value = value(ci.operators[0]) / tmp; break; - case PIEvaluatorTypes::oResidue: + case oResidue: tmpvars[oi].value = residue(value(ci.operators[0]), value(ci.operators[1])); break; - case PIEvaluatorTypes::oPower: + case oPower: tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1])); break; - case PIEvaluatorTypes::oEqual: + case oEqual: tmpvars[oi].value = value(ci.operators[0]) == value(ci.operators[1]); break; - case PIEvaluatorTypes::oNotEqual: + case oNotEqual: tmpvars[oi].value = value(ci.operators[0]) != value(ci.operators[1]); break; - case PIEvaluatorTypes::oGreaterEqual: + case oGreaterEqual: tmpvars[oi].value = value(ci.operators[0]).real() >= value(ci.operators[1]).real(); break; - case PIEvaluatorTypes::oSmallerEqual: + case oSmallerEqual: tmpvars[oi].value = value(ci.operators[0]).real() <= value(ci.operators[1]).real(); break; - case PIEvaluatorTypes::oGreater: + case oGreater: tmpvars[oi].value = value(ci.operators[0]).real() > value(ci.operators[1]).real(); break; - case PIEvaluatorTypes::oSmaller: + case oSmaller: tmpvars[oi].value = value(ci.operators[0]).real() < value(ci.operators[1]).real(); break; - case PIEvaluatorTypes::oAnd: + case oAnd: tmpvars[oi].value = value(ci.operators[0]).real() > 0. && value(ci.operators[1]).real() > 0.; break; - case PIEvaluatorTypes::oOr: + case oOr: tmpvars[oi].value = value(ci.operators[0]).real() > 0. || value(ci.operators[1]).real() > 0.; break; - case PIEvaluatorTypes::oFunction: + case oFunction: execFunction(ci); break; - case PIEvaluatorTypes::oNone: + case oNone: tmpvars[oi].value = value(ci.operators[0]); break; default: break; diff --git a/src_main/math/pievaluator.h b/src_main/math/pievaluator.h index d5a12f80..33d14136 100755 --- a/src_main/math/pievaluator.h +++ b/src_main/math/pievaluator.h @@ -33,7 +33,7 @@ namespace PIEvaluatorTypes { enum PIP_EXPORT eType {etNumber, etOperator, etVariable, etFunction}; enum PIP_EXPORT Operation {oNone, oAdd, oSubtract, oMultiply, oDivide, oResidue, oPower, oEqual, oNotEqual, oGreater, oSmaller, oGreaterEqual, oSmallerEqual, - oAnd, oOr, oOperatorsCount, oFunction + oAnd, oOr, oFunction }; enum PIP_EXPORT BaseFunctions {bfUnknown, bfSin, bfCos, bfTg, bfCtg, bfArcsin, bfArccos, bfArctg, bfArcctg, @@ -215,7 +215,7 @@ private: bool execInstructions(); PIString inBrackets(const PIString & string); PIString operationChar(const PIEvaluatorTypes::Operation & operation); - PIEvaluatorTypes::Operation operationInOrder(const int & index); + void operationsByPriority(int p, PIVector & ret); complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return kvars->at(index).value;} inline complexd residue(const complexd & f, const complexd & s); inline void execFunction(const PIEvaluatorTypes::Instruction & ci);