diff --git a/benchMark.txt b/benchMark.txt index 6c2914aa6292350f861db7cc96dc18d9a226901d..f2f0ea3e95d31e77465e25bd60bbbd478b91f648 100644 --- a/benchMark.txt +++ b/benchMark.txt @@ -15,7 +15,7 @@ NMSEproblem331 1/(x+1) - 1/x NMSEproblem333 1/(1+x) - 2/x + 1/(x - 1) NMSEproblem334 pow((x+1.0),1.0/3.0) - pow(x,1.0/3.0) NMSEproblem336 log(x+1) - log(x) -NMSEproblem337 exp(x) - 2+exp(-x) +NMSEproblem337 exp(x) + (-2) + exp(-x) NMSEproblem341 (1 - cos(x))/(x*x) NMSEproblem343 log((1 - x)/(1 + x)) NMSEproblem344 sqrt((exp(2*x) - 1)/(exp(x) - 1)) @@ -32,8 +32,8 @@ verhulst (4*x)/(1+x/1.11) ComplexSinCos 1.0/2.0*sin(r)*(exp(-i) - exp(i)) ComplexSquareRoot 1.0/2.0*sqrt(2.0*(sqrt(x1*x1+x2*x2)+x1)) doppler1 ((-(1657.0/5.0+3.0/5.0*T))*v)/(((1657.0/5.0+3.0/5.0*T)+u)*((1657.0/5.0+3.0/5.0*T)+u)) -doppler2 ((-(1657/5+3/5*T))*v)/(((1657/5+3/5*T)+u)*((1657/5+3/5*T)+u)) -doppler3 ((-(1657/5+3/5*T))*v)/(((1657/5+3/5*T)+u)*((1657/5+3/5*T)+u)) +doppler2 ((-(1657.0/5.0+3.0/5.0*T))*v)/(((1657.0/5.0+3.0/5.0*T)+u)*((1657.0/5.0+3.0/5.0*T)+u)) +doppler3 ((-(1657.0/5.0+3.0/5.0*T))*v)/(((1657.0/5.0+3.0/5.0*T)+u)*((1657.0/5.0+3.0/5.0*T)+u)) hypot32 sqrt(x1*x1+x2*x2) i4 sqrt(x+y*y) i6 sin(x*y) diff --git a/include/basic.hpp b/include/basic.hpp index 430e465514a2f27fe1f20555c7707f8154b01a45..c3847872dc909dfc87649af02c98e4b7abc0a71b 100644 --- a/include/basic.hpp +++ b/include/basic.hpp @@ -244,7 +244,7 @@ vector> combination(const int num, const vector& indexs); size_t combination(size_t k, size_t n); -void write_to_file(const string &uniqueLabel, const std::vector &data, const std::string &filename); +void write_to_file(const string &uniqueLabel, const string &exprOriginBest, const std::vector &data, const std::string &filename); // } // end anonymous namespace diff --git a/include/devideUpEdgeData.hpp b/include/devideUpEdgeData.hpp index 2f3b48673e6d81a3ccc140cf4ea2ffdcda381396..1df875eff76c01b81f19ea7a8f900c1d5d81ecdc 100644 --- a/include/devideUpEdgeData.hpp +++ b/include/devideUpEdgeData.hpp @@ -1,5 +1,5 @@ #ifndef _DEVIDEUPEDGEDATA #define _DEVIDEUPEDGEDATA -// void devideUpEdgeData(string upEdgeFileName, string intervalFileName, double threshold = 2, double thresholdCombine = 101); -vector devideUpEdgeData(string upEdgeFileName, double threshold = 2, double thresholdCombine = 0); +// void devideUpEdgeData(string upEdgeFileName, string intervalFileName, double threshold, double thresholdCombine = 101); +vector devideUpEdgeData(string upEdgeFileName, double &threshold, int &numIntervalsBefore, double thresholdCombine = 0); #endif \ No newline at end of file diff --git a/include/exprAuto.hpp b/include/exprAuto.hpp index 1a74a7c2cca72d7ae6cfe0e6cc001152eb7509af..5f2ef49249a88a7d60ac08aaa3c709c94dbcef7e 100644 --- a/include/exprAuto.hpp +++ b/include/exprAuto.hpp @@ -47,6 +47,8 @@ vector tryRewrite(ast_ptr expr, bool addSelf = true); exprInfo pickTheBest(string uniqueLabel, vector testSet, vector intervals, vector scales); +exprInfo &pickTheBest(const string &uniqueLabel, vector testSet, vector &initExprInfos, const vector &intervals, const vector &scales); + void geneSampleData(); vector createAll(vector &numerators, vector &denominators); diff --git a/include/tools.hpp b/include/tools.hpp index 3b7355ee5afa3c8d982934984da6b6f22b794aa9..234fe935405a22997368ecb8e49cd22d193fe575 100644 --- a/include/tools.hpp +++ b/include/tools.hpp @@ -44,13 +44,13 @@ string geneBoundaryData(string uniqueLabel, string suffix, double &costTime); vector geneBoundaryData(string uniqueLabel, string suffix, vector suffixes, double &costTime); -vector geneIntervalData(vector upEdgeFileNames, string uniqueLabel, vector &thresholds); +vector geneIntervalData(vector upEdgeFileNames, string uniqueLabel, vector &thresholds, int &numIntervalsBefore); vector> getIntervalData(string filename); -vector> getIntervalData(vector upEdgeFileNames, vector &thresholds, vector &intervals); +vector> getIntervalData(vector upEdgeFileNames, vector &thresholds, vector &intervals, int &numIntervalsBefore); -vector rewrite(string exprStr, string uniqueLabel, vector> &intervalData, int &numOfExprs); +vector rewrite(string exprStr, string uniqueLabel, vector> &intervalData, int &numOfExprs, const vector &intervals); vector> permuteMultiVec(vector> vec); diff --git a/src/basic.cpp b/src/basic.cpp index 8149d6d18888331c3fbbaf87294fd3ac24a76ee1..53e83aa18c026e4d91ca6382930d0248874c04f2 100644 --- a/src/basic.cpp +++ b/src/basic.cpp @@ -741,7 +741,7 @@ size_t combination(size_t k, size_t n) return factorial(n) / (factorial(k) * factorial(n - k)); } -void write_to_file(const string &uniqueLabel, const std::vector &data, const std::string &filename) +void write_to_file(const string &uniqueLabel, const string &exprOriginBest, const std::vector &data, const std::string &filename) { std::ofstream outputFile; outputFile.open(filename, std::ios::out | std::ios::app); @@ -749,6 +749,7 @@ void write_to_file(const string &uniqueLabel, const std::vector &data, c if (outputFile.is_open()) { outputFile << uniqueLabel << ", "; + outputFile << exprOriginBest << ", "; for (const auto &val : data) { outputFile << val << ", "; diff --git a/src/devideUpEdgeData.cpp b/src/devideUpEdgeData.cpp index 0f0cd829503e57ae828310a18305d8f0f38ffc06..a0c3201751626343f0e9ffe0cb5e6c1c97982dc5 100644 --- a/src/devideUpEdgeData.cpp +++ b/src/devideUpEdgeData.cpp @@ -73,6 +73,57 @@ void printRegime(const int &num, vector &vector, string fintervalName, fwidth.close(); } +double setThreshold(vector matlabVector) +{ + double maxErr = std::numeric_limits::min(); + double minErr = std::numeric_limits::max(); + for (auto &elem : matlabVector) + { + auto &errorTmp = elem[2]; + if (errorTmp == 0) + continue; + if (errorTmp > maxErr) + maxErr = errorTmp; + if (errorTmp < minErr) + minErr = errorTmp; + } + cout << "[INFO] setThreshold: maxErr of UpEdge: " << maxErr << endl; + cout << "[INFO] setThreshold: minErr of UpEdge: " << minErr << endl; + double threshold = 2; + if (threshold < minErr) + { // need to get high + while (threshold < minErr) + { + threshold = 0.5 * (threshold + maxErr); + } + } + else if (threshold > maxErr) + { // need to get low + double l = 0; + while ((threshold > maxErr) && (threshold != 0.5)) + { + threshold = 0.5 * (threshold + l); + } + if (threshold == 0.5) + { + ; + } + else if (threshold <= maxErr) + { + if (threshold < minErr) + { // need to get high + l = 2; + while (threshold < minErr) + { + threshold = 0.5 * (threshold + l); + } + } + } + } + cout << "[INFO] setThreshold: threshold: " << threshold << endl; + return threshold; +} + void ifRegimeulp(const int &num, vector &vector, std::vector &store_vector, const double &threshold) { double distance; double k, b, tmp; @@ -215,11 +266,11 @@ void interval_merge(vector in_vector, vector &out_vector, co double *temp = in_vector.front(); out_vector.push_back(temp); // cout << out_vector.size() << endl; - for (int i = 2; i < in_vector.size(); i += 2) { + for (int i = 2; i < (int)in_vector.size(); i += 2) { // cout << i << " " << out_vector.size() << endl; // if (in_vector.at(i)[3] < thresholdCombine && in_vector.at(i - 1)[3] > thresholdCombine && in_vector.at(i + 1)[3] > thresholdCombine) { if (in_vector.at(i)[3] < thresholdCombine) { - if (i == in_vector.size() - 2) { + if (i == (int)in_vector.size() - 2) { temp = in_vector.at(i + 1); out_vector.push_back(temp); } else { @@ -232,7 +283,7 @@ void interval_merge(vector in_vector, vector &out_vector, co out_vector.push_back(temp); // temp = in_vector.at(i+1); // out_vector.push_back(temp); - if (i == in_vector.size() - 2) { + if (i == (int)in_vector.size() - 2) { temp = in_vector.at(i + 1); out_vector.push_back(temp); } @@ -261,9 +312,9 @@ vector extractInfo(vector &origin) { return destination; } -vector devideUpEdgeData(string upEdgeFileName, double threshold, double thresholdCombine) { +vector devideUpEdgeData(string upEdgeFileName, double &threshold, int &numIntervalsBefore, double thresholdCombine) { vector intervalData; - // thresholdCombine = 0; // TODO: set thresholdCombine + // thresholdCombine = 0; // upEdgeFileName 文件中有3列,分别是序号、输入、误差。该文件是由matlab生成,故文件中的序号从1开始,而非0。 // matlab_vector可视为二维数组,保存的是 upEdgeFileName 中的边界点数据,包括序号、输入、误差;输出数组元素: int columns = 3; @@ -273,7 +324,10 @@ vector devideUpEdgeData(string upEdgeFileName, double threshold, double exit(EXIT_FAILURE); } - // 初步获取区间信息 + // 获取误差阈值 + threshold = setThreshold(matlab_vector); + + // 初步划分误差区间 vector store_vector; ifRegimeulp(matlab_vector.size(), matlab_vector, store_vector, threshold); // printRegime(store_vector.size(), store_vector, "intervalTmp.txt", "distanceTmp.txt", "widthTmp.txt"); @@ -284,6 +338,7 @@ vector devideUpEdgeData(string upEdgeFileName, double threshold, double // printRegime(output_vector.size(), output_vector, "intervalTmp_beforeCombine.txt", "distanceTmp_beforeCombine.txt", "widthTmp_beforeCombine.txt"); // Merge intervals that are close in distance. + numIntervalsBefore = output_vector.size() / 2; vector merge_vector; interval_merge(output_vector, merge_vector, thresholdCombine); // printRegime(merge_vector.size(), merge_vector, intervalFileName, "distanceTmp_afterCombine.txt", "widthTmp_afterCombine.txt"); diff --git a/src/exprAuto.cpp b/src/exprAuto.cpp index 2a43619c9f94eadeee5849b5244f191f7b13511c..f3a39a6a6866c0d182582b3f6eee2722f18b22be 100644 --- a/src/exprAuto.cpp +++ b/src/exprAuto.cpp @@ -567,7 +567,7 @@ vector mathfuncRewrite(const ast_ptr &expr, bool addSelf) rhsNewASTs.push_back(rhs->Clone()); } auto newASTs = createAllBinary(lhsNewASTs, rhsNewASTs, op); - + deleteTheSame(newASTs); newASTs = dealWithBinOp(newASTs, op); exprsFinal.insert(exprsFinal.end(), std::make_move_iterator(newASTs.begin()), std::make_move_iterator(newASTs.end())); // if(callCount == 1) @@ -1008,6 +1008,38 @@ size_t computeRandomNum(size_t sum) } // for main +exprInfo &pickTheBest(const string &uniqueLabel, vector testSet, vector &initExprInfos, const vector &intervals, const vector &scales) +{ + int bestExprIdx = 0; + double maxError = INFINITY; + double aveError = INFINITY; + bool isSingleParam = true; + if (scales.size() > 1) + { + isSingleParam = false; + } + for (size_t i = 0; i < testSet.size(); i++) + { + auto &exprInfoTmp = initExprInfos.at(i); + string suffixTmp = initExprInfos.at(i).suffix; + cout << "*-*-*-pickTheBest: for item No." << i << ": type = " << suffixTmp << endl; + + // generate function code and test error + exprInfoTmp = testError(uniqueLabel, suffixTmp, intervals, scales, isSingleParam); + // cout << "pickTheBest: for item No." << i << ": maxError: " << exprInfoTmp.maxError << "\n"; + // cout << "pickTheBest: for item No." << i << ": aveError: " << exprInfoTmp.aveError << "\n"; + if ((exprInfoTmp.maxError < maxError) || ((exprInfoTmp.maxError == maxError) && (exprInfoTmp.aveError < aveError))) + { + bestExprIdx = i; + maxError = exprInfoTmp.maxError; + aveError = exprInfoTmp.aveError; + } + } + auto &result = initExprInfos.at(bestExprIdx); + cout << "pick \'" << result.suffix << "\' as the init expression.\n"; + return result; +} + exprInfo pickTheBest(string uniqueLabel, vector testSet, vector intervals, vector scales) { exprInfo result; @@ -1377,9 +1409,10 @@ vector exprAutoWrapper(ast_ptr &expr, const std::vector &interv expr = minusRewrite(expr); combineConstant(expr); - expr = combineConstant1(expr); - sortExpr(expr); printExpr(expr, "exprAutoWrapper: after parse, expr = ", DOUBLE_PRECISION); + auto expr0 = combineConstant1(expr); + sortExpr(expr0); + printExpr(expr0, "exprAutoWrapper: after some prepare, expr = ", DOUBLE_PRECISION); ast_ptr expr1 = simplifyExpr(expr); // Python SymPy simplify combineConstant(expr1); sortExpr(expr1); diff --git a/src/geneCode.cpp b/src/geneCode.cpp index 9e9a6f2a03e19142a15f8f010e844e9ac1cec18f..c3e5dc79668a4ffba495a392c0e24e8b68688b63 100644 --- a/src/geneCode.cpp +++ b/src/geneCode.cpp @@ -238,7 +238,7 @@ void geneHerbieCode(string exprstr, vector cs, string exprname, double v string geneHerbieCode(string uniqueLabel) { map benchmarkHerbie = { - {"Bsplines3", "-pow(x, 3.0) /6.0"}, + {"Bsplines3", "-pow(x, 3.0) /6.0"}, // warning, the origin is -x*x*x/6 {"exp1x", "expm1(x) / x"}, {"exp1x_log", "expm1(x) / x"}, {"intro_example", "(x / (1.0 + pow(x, 3.0))) * fma(x, x, (1.0 - x))"}, @@ -250,44 +250,44 @@ string geneHerbieCode(string uniqueLabel) {"NMSEexample36", "1.0 / ((x * (pow(x, -0.5) + pow((1.0 + x), -0.5))) + (x * (x * fma(pow(x, -0.25), pow(x, -0.25), pow((1.0 + x), -0.5)))))"}, {"NMSEexample37", "expm1(x)"}, {"NMSEexample38", "fma(x, log((1.0 + (1.0 / x))), log1p(x)) + -1.0"}, - {"NMSEexample39", ""}, // if else - {"NMSEproblem331", "-1.0 / fma(x, x, x)"}, - {"NMSEproblem333", "((1.0 / (x + -1.0)) + (1.0 / (1.0 + x))) + (-2.0 / x)"}, + {"NMSEexample39", ""}, // herbie is if-else, the origin is 1/x - 1/tan(x) + {"NMSEproblem331", "-1.0 / fma(x, x, x)"}, // warning, the origin is 1/(x+1) - 1/x + {"NMSEproblem333", "((1.0 / (x + -1.0)) + (1.0 / (1.0 + x))) + (-2.0 / x)"}, // warning, the origin is 1/(1+x) - 2/x + 1/(x - 1) {"NMSEproblem334", "((x + 1.0) - x) / (pow(cbrt((x + 1.0)), 2.0) + (fma((x + 1.0), cbrt(x), (x * cbrt(x))) / (pow(cbrt((x + 1.0)), 2.0) + (cbrt(x) * (cbrt(x) - cbrt((x + 1.0)))))))"}, {"NMSEproblem336", "log1p((1.0 / x))"}, - {"NMSEproblem337", ""}, // if else + {"NMSEproblem337", ""}, // herbie is if-else, the origin is exp(x) + (-2) + exp(-x) {"NMSEproblem341", "(sin(x) / x) * (tan((x / 2.0)) / x)"}, {"NMSEproblem343", "log1p(-x) - log1p(x)"}, {"NMSEproblem344", "sqrt((1.0 + exp(x)))"}, {"NMSEproblem345", ""}, // if else {"NMSEsection311", "(1.0 + expm1(x)) / expm1(x)"}, - {"predatorPrey", ""}, // x * ((x * 4.0) * exp(-log1p(sqrt(pow((x * 0.9009009009009009), 4.0))))) - {"sine", ""}, // x - fma(0.0001984126984126984, pow(x, 7.0), fma(0.16666666666666666, pow(x, 3.0), (-0.008333333333333333 * pow(x, 5.0)))) // this one can not rewrite well, so arfa will use origin - {"sineorder3", ""}, // fma(x, 0.954929658551372, (pow(x, 3.0) * -0.12900613773279798)) // this one can not rewrite well, so arfa will use origin - {"sqroot", ""}, // fma(x, (0.5 + (x * fma(x, fma(x, -0.0390625, 0.0625), -0.125))), 1.0) // this one can not rewrite well, so arfa will use origin + {"predatorPrey", "x * ((x * 4.0) * exp(-log1p(sqrt(pow((x * 0.9009009009009009), 4.0)))))"}, // warning, the origin is ((4.0 * x) * x) / (1.0 + ((x / 1.11) * (x / 1.11))) + {"sine", "x - fma(0.0001984126984126984, pow(x, 7.0), fma(0.16666666666666666, pow(x, 3.0), (-0.008333333333333333 * pow(x, 5.0))))"}, // warning, the origin is x - (1.0/6.0)*x*x*x+(1.0/120.0)*x*x*x*x*x - (1.0/5040.0)*x*x*x*x*x*x*x + {"sineorder3", "fma(x, 0.954929658551372, (pow(x, 3.0) * -0.12900613773279798))"}, // warning, the origin is (238732414637843.0/250000000000000.0)*x - (6450306886639899.0/50000000000000000.0)*x*x*x + {"sqroot", "fma(x, (0.5 + (x * fma(x, fma(x, -0.0390625, 0.0625), -0.125))), 1.0)"}, // warning, the origin is 1.0 + 0.5*x - 0.125*x*x + 0.0625*x*x*x - 0.0390625*x*x*x*x {"sqrt_add", "1.0 / (sqrt((1.0 + x)) + sqrt(x))"}, - {"test05_nonlin1_r4", ""}, // exp(-log1p(x)) // this one can not rewrite well, so arfa will use origin - {"test05_nonlin1_test2", ""}, // exp(-log1p(x)) // this one can not rewrite well, so arfa will use origin - {"verhulst", ""}, // pow(log1p(expm1((64.0 * pow((x / fma(x, 0.9009009009009009, 1.0)), 3.0)))), 0.3333333333333333); // this one can not rewrite well, so arfa will use origin - {"ComplexSinCos", ""}, - {"ComplexSquareRoot", ""}, - {"doppler1", ""}, - {"doppler2", ""}, - {"doppler3", ""}, - {"hypot32", ""}, - {"i4", ""}, - {"i6", ""}, - {"NMSEexample33", ""}, - {"NMSEproblem332", ""}, - {"NMSEproblem335", ""}, - {"NMSEproblem346", ""}, - {"NMSEsection35", ""}, - {"polarToCarthesianX", ""}, - {"polarToCarthesianY", ""}, - {"sec4example", ""}, - {"test03_nonlin2", ""}, - {"theta", ""}, - {"turbine1", ""}, + {"test05_nonlin1_r4", "exp(-log1p(x))"}, // warning, the origin is (x - 1)/(x*x - 1) + {"test05_nonlin1_test2", "exp(-log1p(x))"}, // warning, the origin is 1.0/(1+x) + {"verhulst", "pow(log1p(expm1((64.0 * pow((x / fma(x, 0.9009009009009009, 1.0)), 3.0)))), 0.3333333333333333)"}, // warning, the origin is (4*x)/(1+x/1.11) + {"ComplexSinCos", "sin(x1) * ((pow(x2, 3.0) * -0.16666666666666666) - x2)"}, + {"ComplexSquareRoot", "0.5 * sqrt((2.0 * (x1 + hypot(x1, x2))))"}, + {"doppler1", "(fma(x2, -0.6, -331.4) / pow((331.4 + fma(0.6, x2, x0)), 2.0)) * x1"}, // warning, the origin is ((-(1657.0/5.0+3.0/5.0*T))*v)/(((1657.0/5.0+3.0/5.0*T)+u)*((1657.0/5.0+3.0/5.0*T)+u)) + {"doppler2", ""}, // warning, the origin is ((-(1657.0/5.0+3.0/5.0*T))*v)/(((1657.0/5.0+3.0/5.0*T)+u)*((1657.0/5.0+3.0/5.0*T)+u)) + {"doppler3", ""}, // warning, the origin is ((-(1657.0/5.0+3.0/5.0*T))*v)/(((1657.0/5.0+3.0/5.0*T)+u)*((1657.0/5.0+3.0/5.0*T)+u)) + {"hypot32", "hypotf(x1, x2)"}, // single precision + {"i4", "sqrtf(fmaf(f2, f2, f1))"}, // single precision + {"i6", "sinf((f1 * f2))"}, // single precision + {"NMSEexample33", "fma(x1, fma((x1 * -0.5), sin(x2), (cos(x2) + -1.0)), sin(x2))"}, + {"NMSEproblem332", "fma(sin(x2) / cos(x2), (x1 * (x1 + (pow(sin(x2), 2.0) / (pow(cos(x2), 2.0) / x1)))), fma((pow(sin(x2), pow(cos(x2), 2.0)) / t_2), x1, sin(x2) / cos(x2)))"}, // double t_0 = sin(x2) / cos(x2); double t_1 = pow(sin(x2), 2.0); double t_2 = pow(cos(x2), 2.0); *resultPtr = fma(t_0, (x1 * (x1 + (t_1 / (t_2 / x1)))), fma((t_1 / t_2), x1, t_0)); + {"NMSEproblem335", "-2.0 * (sin(((x2 + (x1 - x1)) * 0.5)) * sin((0.5 * fma(x1, 2.0, x2))))"}, + {"NMSEproblem346", ""}, // expm1(log1p((exp((log1p(x1) / x2)) - pow(x1, (1.0 / x2))))) + {"NMSEsection35", "expm1((a * x))"}, + {"polarToCarthesianX", "x1 * cos(log((pow(sqrt(exp(0.017453292519944444)), x2) * fma(0.5, (pow(log(sqrt(exp(0.017453292519944444))), 2.0) * (x2 * x2)), fma(log(sqrt(exp(0.017453292519944444))), x2, fma(pow(x2, 3.0), (0.16666666666666666 * pow(log(sqrt(exp(0.017453292519944444))), 3.0)), 1.0))))))"}, // double t_1 = sqrt(exp(0.017453292519944444)); double t_2 = log(t_1); *resultPtr = x1 * cos(log((pow(t_1, x2) * fma(0.5, (pow(t_2, 2.0) * (x2 * x2)), fma(t_2, x2, fma(pow(x2, 3.0), (0.16666666666666666 * pow(t_2, 3.0)), 1.0)))))); + {"polarToCarthesianY", "exp((((log(0.017453292519944444) * log(0.017453292519944444)) + (0.0 - pow(pow(log((x1 * x2)), 6.0), 0.3333333333333333))) / (log(0.017453292519944444) - log((x1 * x2)))))"}, // double t_1 = log((x1 * x2)); *resultPtr = exp((((log(0.017453292519944444) * log(0.017453292519944444)) + (0.0 - pow(pow(t_1, 6.0), 0.3333333333333333))) / (log(0.017453292519944444) - t_1))); + {"sec4example", "pow(fma(x1, x2, 1.0), -1.0)"}, // warning, the origin is ((x1*x2) - 1)/((x1*x2)*(x1*x2) - 1) + {"test03_nonlin2", ""}, // for test03_nonlin2, herbie is the same to origin + {"theta", "(pow(pow(cbrt(cbrt(cbrt(cbrt((atan((x2 / x1)) * 57.29577951307855))))), 2.0), 18.0) * pow(cbrt(cbrt(cbrt(cbrt((atan((x2 / x1)) * 57.29577951307855))))), 18.0)) * pow(cbrt(cbrt(cbrt((atan((x2 / x1)) * 57.29577951307855)))), 9.0)"}, // double t_0 = cbrt(cbrt(cbrt((atan((x2 / x1)) * 57.29577951307855)))); double t_1 = cbrt(t_0); *resultPtr = (pow(pow(t_1, 2.0), 18.0) * pow(t_1, 18.0)) * pow(t_0, 9.0) + {"turbine1", "cbrt(pow((2.0 * pow(x2, -2.0)), 3.0)) - fma(fma(x0, -0.25, 0.375), ((x2 / (1.0 - x0)) * (x2 * pow(x1, 2.0))), 1.5)"}, // warning, the origin is (2.0/(r*r)+3.0) - ((3.0 - 2.0*v)*(1.0/8.0)*((w*w)*r*r))/(1.0 - v) - 9.0/2.0 }; auto pos = benchmarkHerbie.find(uniqueLabel); diff --git a/src/main.cpp b/src/main.cpp index ba20c6ca6a220cf2f354b63f94f57062478d85bb..691f89a97f2935db671e6d1e6dba67afe21ea2d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -105,8 +105,8 @@ int main() fprintf(stderr, GREEN "ready> " RESET); string inputStr = ""; - // while (getline(infile, inputStr)) // read line from file's input - while (getline(cin, inputStr)) // read line from keyboard input + while (getline(infile, inputStr)) // read line from file's input + // while (getline(cin, inputStr)) // read line from keyboard input { // only rewrite // getlineCount++; @@ -173,29 +173,6 @@ int main() intervals = getIntervals(intervalStr, split); } - // For temporary use only . It will be replaced by geneBoundaryData and geneIntervalData - // ofstream ofs; - // ofs.open("intervalData.txt", ios::out); - // TODO-DONE: (but no need do it): judge if intervals.size() == dimension - // for (int i = 0; i < dimension; i++) - // { - // if (i == dimension - 1) - // { - // ofs << intervals.at(i); - // } - // else - // { - // ofs << intervals.at(i) << " "; - // } - // } - // ofs.close(); - - // Read scale from keyboard - // fprintf(stderr, GREEN "scale> " RESET); - // string scaleStr; - // getline(cin, scaleStr); - // vector scales = getScales(scaleStr, split); - // Default scale setting according to the variables' size int sampleScale; if (dimension == 1) @@ -223,13 +200,24 @@ int main() bool runAllFlag = true; // ready for writing to file + string exprOriginBest = ""; double originPerformance = -1; + int numIntervalsBefore = -1; double numOfIntervals = -1; int numOfExprs = -1; exprInfo finalInfo; // ave err, max err, performance std::chrono::duration init_seconds, matlab_seconds, regime_seconds, rewrite_seconds, final_seconds,elapsed_seconds; double matlabKernelTime = -1; - + vector initExprInfos; + exprInfo tempExprInfo; + tempExprInfo.suffix = "origin"; + initExprInfos.push_back(tempExprInfo); + tempExprInfo.suffix = "herbie"; + initExprInfos.push_back(tempExprInfo); + auto &originExprInfo = initExprInfos.at(0); + auto &herbieExprInfo = initExprInfos.at(1); + herbieExprInfo.aveError = -1; + herbieExprInfo.maxError = -1; if (runAllFlag) { // the whole process if (!isBenchMark) @@ -261,19 +249,21 @@ int main() { fprintf(stderr, "For exprOrigin, Herbie's rewrite results can not be used.\nSo, we just pick origin as the best.\n"); } - auto initExprInfo = pickTheBest(uniqueLabel, suffixSet, intervals, scales); - auto suffix = initExprInfo.suffix; - if (suffix == "origin") + + auto &initExprInfo = pickTheBest(uniqueLabel, suffixSet, initExprInfos, intervals, scales); + exprOriginBest = initExprInfo.suffix; + + if (exprOriginBest == "origin") { inputStr = exprOrigin; } - else if (suffix == "herbie") + else if (exprOriginBest == "herbie") { inputStr = exprHerbie; } else { - fprintf(stderr, "ERROR: main: we do not support the suffix %s now\n", suffix.c_str()); + fprintf(stderr, "ERROR: main: we do not support the suffix %s now\n", exprOriginBest.c_str()); exit(EXIT_FAILURE); } cout << "the pick expr is " << inputStr << "\n"; @@ -288,24 +278,13 @@ int main() continue; } - // cout << BLUE << "main: start testError for origin: " << inputStr << RESET << endl; - // auto timeTmp1 = std::chrono::high_resolution_clock::now(); - // geneSampleData(); - // auto infoTmp = testError(uniqueLabel, "origin", intervals, scales); - // auto timeTmp2 = std::chrono::high_resolution_clock::now(); - // cout << BLUE << "main: ending testError for origin: " << inputStr << RESET << endl; - // std::chrono::duration testError_seconds = timeTmp2 - timeTmp1; - // cout << BLUE << "testError time: " << testError_seconds.count() << " s" << RESET << endl; - // fprintf(stderr, GREEN "ready> " RESET); - // continue; - string upEdgeFileName; vector upEdgeFileNames; if(dimension == 1) { // No sampling is required because for a single parameter, the error test data is equivalent to the sampled data // Just generate boundary data by matlab - upEdgeFileName = geneBoundaryData(uniqueLabel, suffix, matlabKernelTime); // sample data == matlab ==> upEdge data + upEdgeFileName = geneBoundaryData(uniqueLabel, exprOriginBest, matlabKernelTime); // sample data == matlab ==> upEdge data upEdgeFileNames.push_back(upEdgeFileName); } else @@ -316,37 +295,38 @@ int main() vector suffixTmps; if (dimension == 2) { - suffixTmp = suffix + "_X"; + suffixTmp = exprOriginBest + "_X"; suffixTmps.push_back(suffixTmp); - suffixTmp = suffix + "_Y"; + suffixTmp = exprOriginBest + "_Y"; suffixTmps.push_back(suffixTmp); vector scales{8192, 2048}; - sampleError(uniqueLabel, suffix, intervals, scales); + sampleError(uniqueLabel, exprOriginBest, intervals, scales); } else if (dimension == 3) { - suffixTmp = suffix + "_X"; + suffixTmp = exprOriginBest + "_X"; suffixTmps.push_back(suffixTmp); - suffixTmp = suffix + "_Y"; + suffixTmp = exprOriginBest + "_Y"; suffixTmps.push_back(suffixTmp); - suffixTmp = suffix + "_Z"; + suffixTmp = exprOriginBest + "_Z"; suffixTmps.push_back(suffixTmp); vector scales{512, 128}; // actually are drawNum and findMaxNum, so only need 2 numbers - sampleError(uniqueLabel, suffix, intervals, scales); + sampleError(uniqueLabel, exprOriginBest, intervals, scales); } else { fprintf(stderr, "ERROR: main: we can not handle %d parameters (bigger than 3) now\n", dimension); exit(EXIT_FAILURE); } - upEdgeFileNames = geneBoundaryData(uniqueLabel, suffix, suffixTmps, matlabKernelTime); // sample data == matlab ==> upEdge data + upEdgeFileNames = geneBoundaryData(uniqueLabel, exprOriginBest, suffixTmps, matlabKernelTime); // sample data == matlab ==> upEdge data } fmt::print("upEdgeFileNames: {}\n", upEdgeFileNames); auto timeTmp2 = std::chrono::high_resolution_clock::now(); // matlab over matlab_seconds = timeTmp2 - timeTmp1; cout << BLUE << "regime time (matlab part): " << matlab_seconds.count() << " s" << RESET << endl; - auto intervalData = getIntervalData(upEdgeFileNames, thresholds, intervals); + auto intervalData = getIntervalData(upEdgeFileNames, thresholds, intervals, numIntervalsBefore); + // fmt::print("[INFO] main: thresholds {}\n", thresholds); numOfIntervals = intervalData.size(); fmt::print("after regime, we have {} intervals: {}\n", numOfIntervals, intervalData); auto timeTmp3 = std::chrono::high_resolution_clock::now(); @@ -356,7 +336,7 @@ int main() // continue; cout << "=-=-=-=-=-=-=-=-=-=-=-=-= rewrite start =-=-=-=-=-=-=-=-=-=-=-=-=" << endl; - auto exprInfoVector = rewrite(inputStr, uniqueLabel, intervalData, numOfExprs); + auto exprInfoVector = rewrite(inputStr, uniqueLabel, intervalData, numOfExprs, intervals); auto timeTmp4 = std::chrono::high_resolution_clock::now(); // rewrite over rewrite_seconds = timeTmp4 - timeTmp3; cout << BLUE << "rewrite time: " << rewrite_seconds.count() << " s" << RESET << endl; @@ -416,11 +396,36 @@ int main() cout << BLUE << "the whole time: " << elapsed_seconds.count() << " s" << RESET << endl; vector summaryData; - summaryData.push_back(originPerformance); + summaryData.push_back(dimension); + summaryData.push_back(numIntervalsBefore); summaryData.push_back(numOfIntervals); summaryData.push_back(double(numOfExprs)); + if(thresholds.size() == 1) { + summaryData.push_back(thresholds.at(0)); + summaryData.push_back(-1); + summaryData.push_back(-1); + } + else if(thresholds.size() == 2) { + summaryData.push_back(thresholds.at(0)); + summaryData.push_back(thresholds.at(1)); + summaryData.push_back(-1); + } + else if(thresholds.size() == 3) { + summaryData.push_back(thresholds.at(0)); + summaryData.push_back(thresholds.at(1)); + summaryData.push_back(thresholds.at(2)); + } + else { + fprintf(stderr, "ERROR: we can not support %ld demision now.\n", thresholds.size()); + exit(EXIT_FAILURE); + } + summaryData.push_back(originExprInfo.aveError); + summaryData.push_back(herbieExprInfo.aveError); summaryData.push_back(finalInfo.aveError); + summaryData.push_back(originExprInfo.maxError); + summaryData.push_back(herbieExprInfo.maxError); summaryData.push_back(finalInfo.maxError); + summaryData.push_back(originPerformance); summaryData.push_back(finalInfo.performance); summaryData.push_back(elapsed_seconds.count()); summaryData.push_back(init_seconds.count()); @@ -429,7 +434,7 @@ int main() summaryData.push_back(rewrite_seconds.count()); summaryData.push_back(final_seconds.count()); summaryData.push_back(matlabKernelTime); - write_to_file(uniqueLabel, summaryData, "runlog.csv"); + write_to_file(uniqueLabel, exprOriginBest, summaryData, "runlog.csv"); fprintf(stderr, GREEN "ready> " RESET); } diff --git a/src/tools.cpp b/src/tools.cpp index 3f0fb13c5a1daa09f2a2d83d75de8d9ae041133f..d0764264d65b99f57c9091e5edf07c197c53dc82 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -438,7 +438,7 @@ exprInfo testError(string uniqueLabel, string suffix, const vector &inte tempError.aveError = atof(aveErrorTemp.c_str()); tempError.maxError = atof(maxErrorTemp.c_str()); } - + tempError.suffix = suffix; return tempError; } else if (size == 4) @@ -757,7 +757,7 @@ vector> getIntervalData(string filename) } // according to the corresponding upEdgeFile, generate intervalData for each dimension, and then combine all permutation of all dimensions. -vector> getIntervalData(vector upEdgeFileNames, vector &thresholds, vector &intervals) +vector> getIntervalData(vector upEdgeFileNames, vector &thresholds, vector &intervals, int &numIntervalsBefore) { vector> intervalDataMultiDim; int dimension = thresholds.size(); @@ -767,8 +767,8 @@ vector> getIntervalData(vector upEdgeFileNames, vector> getIntervalData(vector upEdgeFileNames, vector rewrite(string exprStr, string uniqueLabel, vector> &intervalData, int &numOfExprs) +vector rewrite(string exprStr, string uniqueLabel, vector> &intervalData, int &numOfExprs, const vector &intervals) { // string filename = "expr_" + uniqueLabel + "_interval.txt"; // useless // string filename = "./intervalData.txt"; // TODO-done: get the filename from uniqueLabel. Now we get intervalData from input parameters directly. @@ -801,6 +801,22 @@ vector rewrite(string exprStr, string uniqueLabel, vector scales(dimension, scale); + for (int i = 0; i < dimension; i++) + { + double width = intervals.at(i * 2 + 1) - intervals.at(i * 2); + double step = width / (double)scales.at(i); + int stepNum = (intervalTmp.at(i * 2) - intervals.at(i * 2)) / step; + int stepNum1 = (intervalTmp.at(i * 2 + 1) - intervals.at(i * 2)) / step; + if(stepNum == stepNum1) + { + stepNum1 += 1; + } + scales.at(i) = stepNum1 - stepNum; + + intervalTmp.at(i * 2) = intervals.at(i * 2) + stepNum * step; + intervalTmp.at(i * 2 + 1) = intervals.at(i * 2) + stepNum1 * step; + // scales.at(i) = scales.at(i) * (intervalTmp.at(i * 2 + 1) - intervalTmp.at(i * 2)) / width; + } auto newTempExprs = exprAutoWrapper(tempExpr, intervalTmp, scales); numOfExprs = newTempExprs.size(); string suffix = "temp_" + std::to_string(count) + "_";