diff --git a/ADOL-C/boost-test/traceOperatorVector.cpp b/ADOL-C/boost-test/traceOperatorVector.cpp index 799264ff..f8720621 100644 --- a/ADOL-C/boost-test/traceOperatorVector.cpp +++ b/ADOL-C/boost-test/traceOperatorVector.cpp @@ -2507,11 +2507,11 @@ BOOST_AUTO_TEST_CASE(FmaxOperator_FOV_Forward_1) { xd[0][0] = 1.3; xd[0][1] = 3.7; xd[1][0] = -1.3; - xd[1][0] = -3.7; + xd[1][1] = -3.7; a = std::fmax(2.5, 2.5); - aDerivative = 1.3; - bDerivative = 1.3; + aDerivative = std::fmax(xd[0][0], xd[1][0]); + bDerivative = std::fmax(xd[0][1], xd[1][1]); fov_forward(1, 1, 2, 2, x, xd, y, yd); @@ -2729,6 +2729,7 @@ BOOST_AUTO_TEST_CASE(FmaxOperator_FOV_Forward_3) { trace_off(); double aDerivative = 1.; + double bDerivative = 1.; a = std::fmax(a, b); double *x = myalloc1(1); @@ -2770,13 +2771,14 @@ BOOST_AUTO_TEST_CASE(FmaxOperator_FOV_Forward_3) { } a = std::fmax(x[0], b); - aDerivative = 1.; + aDerivative = std::fmax(xd[0][0], 0.0); + bDerivative = std::fmax(xd[0][1], 0.0); fov_forward(1, 1, 1, 2, x, xd, y, yd); BOOST_TEST(*y == a, tt::tolerance(tol)); BOOST_TEST(yd[0][0] == aDerivative, tt::tolerance(tol)); - BOOST_TEST(yd[0][1] == aDerivative, tt::tolerance(tol)); + BOOST_TEST(yd[0][1] == bDerivative, tt::tolerance(tol)); myfree1(x); myfree2(xd); @@ -2900,11 +2902,11 @@ BOOST_AUTO_TEST_CASE(FminOperator_FOV_Forward_1) { xd[0][0] = 1.3; xd[0][1] = 3.7; xd[1][0] = -1.3; - xd[1][0] = -3.7; + xd[1][1] = -3.7; - a = std::fmax(2.5, 2.5); - aDerivative = -3.7; - bDerivative = -3.7; + a = std::fmin(2.5, 2.5); + aDerivative = std::fmin(xd[0][0], xd[1][0]); + bDerivative = std::fmin(xd[0][1], xd[1][1]); fov_forward(1, 1, 2, 2, x, xd, y, yd); @@ -3122,6 +3124,7 @@ BOOST_AUTO_TEST_CASE(FminOperator_FOV_Forward_3) { trace_off(); double aDerivative = 0.; + double bDerivative = 0.; a = std::fmin(a, b); double *x = myalloc1(1); @@ -3163,13 +3166,14 @@ BOOST_AUTO_TEST_CASE(FminOperator_FOV_Forward_3) { } a = std::fmin(x[0], b); - aDerivative = 0.; + aDerivative = std::fmin(xd[0][0], 0.0); + bDerivative = std::fmin(xd[0][1], 0.0); fov_forward(1, 1, 1, 2, x, xd, y, yd); BOOST_TEST(*y == a, tt::tolerance(tol)); BOOST_TEST(yd[0][0] == aDerivative, tt::tolerance(tol)); - BOOST_TEST(yd[0][1] == aDerivative, tt::tolerance(tol)); + BOOST_TEST(yd[0][1] == bDerivative, tt::tolerance(tol)); myfree1(x); myfree2(xd); diff --git a/ADOL-C/boost-test/uni5_for.cpp b/ADOL-C/boost-test/uni5_for.cpp index 593ec756..e3e19b2d 100644 --- a/ADOL-C/boost-test/uni5_for.cpp +++ b/ADOL-C/boost-test/uni5_for.cpp @@ -18,19 +18,17 @@ namespace tt = boost::test_tools; BOOST_AUTO_TEST_SUITE(uni5_for) -BOOST_AUTO_TEST_CASE(ZOS_PL_FORWARD) { - - enableMinMaxUsingAbs(); - +BOOST_AUTO_TEST_CASE(Fmaxoperator_ZOS_PL_Forward) { const int16_t tag = 1; const int dim_out = 1; const int dim_in = 3; - std::array in = {-2.0, 0.0, 1.5}; + std::array in{-2.0, 0.0, 1.5}; std::array indep; double out[] = {0.0}; + enableMinMaxUsingAbs(); // ---------------------- trace on --------------------- // function is given by fabs(in_2 + fabs(in_1 + fabs(in_0))) trace_on(tag); @@ -48,7 +46,7 @@ BOOST_AUTO_TEST_CASE(ZOS_PL_FORWARD) { dep >>= out[0]; trace_off(); - + disableMinMaxUsingAbs(); // ---------------------- trace off --------------------- // test outout @@ -82,4 +80,325 @@ BOOST_AUTO_TEST_CASE(ZOS_PL_FORWARD) { removeTape(tag, ADOLC_REMOVE_COMPLETELY); } + +BOOST_AUTO_TEST_CASE(FmaxOperator_HOV_Forward) { + const int16_t tag = 0; + const size_t dim_out = 1; + const size_t dim_in = 2; + const size_t degree = 2; + const size_t num_dirs = 3; + std::vector in{4.0, 3.2}; + std::vector indep(dim_in); + std::vector out(dim_out); + + trace_on(tag); + std::for_each(in.begin(), in.end(), [&, i = 0](int value) mutable { + indep[i] <<= in[i]; + i++; + }); + + // max(x^2, y^3) + adouble dep = fmax(pow(indep[0], 2), pow(indep[1], 3)); + + dep >>= out[0]; + trace_off(); + + double ***X = myalloc3(dim_in, num_dirs, degree); + double ***Y = myalloc3(dim_out, num_dirs, degree); + + X[0][0][0] = 1.0; + X[1][0][0] = 1.9; + + X[0][1][0] = 2.0; + X[1][1][0] = 3.0; + + X[0][2][0] = 1.0; + X[1][2][0] = -1.0; + + X[0][0][1] = -1.0; + X[1][0][1] = 1.0; + + X[0][1][1] = -2.0; + X[1][1][1] = -3.0; + + X[0][2][1] = -1.0; + X[1][2][1] = 1.0; + + /**************************** + TEST A < B + *****************************/ + std::vector test_in{4.0, 3.2}; + // max(x^2, y^3) + double test_out = std::fmax(std::pow(test_in[0], 2), std::pow(test_in[1], 3)); + + hov_forward(tag, dim_out, dim_in, degree, num_dirs, test_in.data(), X, + out.data(), Y); + + BOOST_TEST(out[0] == test_out, tt::tolerance(tol)); + BOOST_TEST(Y[0][0][0] == 3 * std::pow(test_in[1], 2) * X[1][0][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][1][0] == 3 * std::pow(test_in[1], 2) * X[1][1][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][2][0] == 3 * std::pow(test_in[1], 2) * X[1][2][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][0][1] == + 1.0 / 2.0 * 6.0 * test_in[1] * X[1][0][0] * X[1][0][0] + + 3.0 * std::pow(test_in[1], 2.0) * X[1][0][1], + tt::tolerance(tol)); + BOOST_TEST(Y[0][1][1] == + 1.0 / 2.0 * 6.0 * test_in[1] * X[1][1][0] * X[1][1][0] + + 3.0 * std::pow(test_in[1], 2.0) * X[1][1][1], + tt::tolerance(tol)); + BOOST_TEST(Y[0][2][1] == + 1.0 / 2.0 * 6.0 * test_in[1] * X[1][2][0] * X[1][2][0] + + 3.0 * std::pow(test_in[1], 2.0) * X[1][2][1], + tt::tolerance(tol)); + + /************************** + TEST A > B + ***************************/ + + // test_in[0] = 4.0 + test_in[1] = 1.0; + // max(x^2, y^3) + test_out = std::fmax(std::pow(test_in[0], 2), std::pow(test_in[1], 3)); + hov_forward(tag, dim_out, dim_in, degree, num_dirs, test_in.data(), X, + out.data(), Y); + + BOOST_TEST(out[0] == test_out, tt::tolerance(tol)); + BOOST_TEST(Y[0][0][0] == 2 * test_in[0] * X[0][0][0], tt::tolerance(tol)); + BOOST_TEST(Y[0][1][0] == 2 * test_in[0] * X[0][1][0], tt::tolerance(tol)); + BOOST_TEST(Y[0][2][0] == 2 * test_in[0] * X[0][2][0], tt::tolerance(tol)); + BOOST_TEST(Y[0][0][1] == 1.0 / 2.0 * 2.0 * X[0][0][0] * X[0][0][0] + + 2.0 * test_in[0] * X[0][0][1], + tt::tolerance(tol)); + BOOST_TEST(Y[0][1][1] == 1.0 / 2.0 * 2.0 * X[0][1][0] * X[0][1][0] + + 2.0 * test_in[0] * X[0][1][1], + tt::tolerance(tol)); + BOOST_TEST(Y[0][2][1] == 1.0 / 2.0 * 2.0 * X[0][2][0] * X[0][2][0] + + 2.0 * test_in[0] * X[0][2][1], + tt::tolerance(tol)); + + /************************** + TEST A == B + ***************************/ + + test_in[0] = 1.0; + test_in[1] = 1.0; + + // max(x^2, y^3) + test_out = std::fmax(std::pow(test_in[0], 2), std::pow(test_in[1], 3)); + + // A < B + X[0][0][0] = 1.0; + X[1][0][0] = 1.9; + + // A > B + X[0][1][0] = 3.0; + X[1][1][0] = 2.0; + + // A == B + X[0][2][0] = 1.0; + X[1][2][0] = 1.0; + + X[0][0][1] = -1.0; + X[1][0][1] = 1.0; + + X[0][1][1] = -2.0; + X[1][1][1] = -3.0; + + // A < B + X[0][2][1] = 1.0; + X[1][2][1] = 2.0; + + hov_forward(tag, dim_out, dim_in, degree, num_dirs, test_in.data(), X, + out.data(), Y); + BOOST_TEST(out[0] == test_out, tt::tolerance(tol)); + + // A < B + BOOST_TEST(Y[0][0][0] == 3 * std::pow(test_in[1], 2) * X[1][0][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][0][1] == + 1.0 / 2.0 * 6.0 * test_in[1] * X[1][0][0] * X[1][0][0] + + 3.0 * std::pow(test_in[1], 2.0) * X[1][0][1], + tt::tolerance(tol)); + + // A < B + BOOST_TEST(Y[0][1][0] == 2 * test_in[0] * X[0][1][0], tt::tolerance(tol)); + BOOST_TEST(Y[0][1][1] == 1.0 / 2.0 * 2.0 * X[0][1][0] * X[0][1][0] + + 2.0 * test_in[0] * X[0][1][1], + tt::tolerance(tol)); + + // A == B, A < B + BOOST_TEST(Y[0][2][0] == 3 * std::pow(test_in[1], 2) * X[1][2][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][2][1] == + 1.0 / 2.0 * 6.0 * test_in[1] * X[1][2][0] * X[1][2][0] + + 3.0 * std::pow(test_in[1], 2.0) * X[1][2][1], + tt::tolerance(tol)); + + myfree3(X); + myfree3(Y); +} + +BOOST_AUTO_TEST_CASE(FminOperator_HOV_Forward) { + const int16_t tag = 0; + const size_t dim_out = 1; + const size_t dim_in = 2; + const size_t degree = 2; + const size_t num_dirs = 3; + std::vector in{4.0, 3.2}; + std::vector indep(dim_in); + std::vector out(dim_out); + + trace_on(tag); + std::for_each(in.begin(), in.end(), [&, i = 0](int value) mutable { + indep[i] <<= in[i]; + i++; + }); + + // max(x^2, y^3) + adouble dep = fmin(-pow(indep[0], 2), -pow(indep[1], 3)); + + dep >>= out[0]; + trace_off(); + + double ***X = myalloc3(dim_in, num_dirs, degree); + double ***Y = myalloc3(dim_out, num_dirs, degree); + + X[0][0][0] = 1.0; + X[1][0][0] = 1.9; + + X[0][1][0] = 2.0; + X[1][1][0] = 3.0; + + X[0][2][0] = 1.0; + X[1][2][0] = -1.0; + + X[0][0][1] = -1.0; + X[1][0][1] = 1.0; + + X[0][1][1] = -2.0; + X[1][1][1] = -3.0; + + X[0][2][1] = -1.0; + X[1][2][1] = 1.0; + + /**************************** + TEST A < B + *****************************/ + std::vector test_in{4.0, 3.2}; + // max(x^2, y^3) + double test_out = + std::fmin(-std::pow(test_in[0], 2), -std::pow(test_in[1], 3)); + + hov_forward(tag, dim_out, dim_in, degree, num_dirs, test_in.data(), X, + out.data(), Y); + + BOOST_TEST(out[0] == test_out, tt::tolerance(tol)); + BOOST_TEST(Y[0][0][0] == -3 * std::pow(test_in[1], 2) * X[1][0][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][1][0] == -3 * std::pow(test_in[1], 2) * X[1][1][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][2][0] == -3 * std::pow(test_in[1], 2) * X[1][2][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][0][1] == + -1.0 / 2.0 * 6.0 * test_in[1] * X[1][0][0] * X[1][0][0] - + 3.0 * std::pow(test_in[1], 2.0) * X[1][0][1], + tt::tolerance(tol)); + BOOST_TEST(Y[0][1][1] == + -1.0 / 2.0 * 6.0 * test_in[1] * X[1][1][0] * X[1][1][0] - + 3.0 * std::pow(test_in[1], 2.0) * X[1][1][1], + tt::tolerance(tol)); + BOOST_TEST(Y[0][2][1] == + -1.0 / 2.0 * 6.0 * test_in[1] * X[1][2][0] * X[1][2][0] - + 3.0 * std::pow(test_in[1], 2.0) * X[1][2][1], + tt::tolerance(tol)); + + /************************** + TEST A > B + ***************************/ + + // test_in[0] = 4.0 + test_in[1] = 1.0; + // max(x^2, y^3) + test_out = std::fmin(-std::pow(test_in[0], 2), -std::pow(test_in[1], 3)); + hov_forward(tag, dim_out, dim_in, degree, num_dirs, test_in.data(), X, + out.data(), Y); + + BOOST_TEST(out[0] == test_out, tt::tolerance(tol)); + BOOST_TEST(Y[0][0][0] == -2 * test_in[0] * X[0][0][0], tt::tolerance(tol)); + BOOST_TEST(Y[0][1][0] == -2 * test_in[0] * X[0][1][0], tt::tolerance(tol)); + BOOST_TEST(Y[0][2][0] == -2 * test_in[0] * X[0][2][0], tt::tolerance(tol)); + BOOST_TEST(Y[0][0][1] == -1.0 / 2.0 * 2.0 * X[0][0][0] * X[0][0][0] - + 2.0 * test_in[0] * X[0][0][1], + tt::tolerance(tol)); + BOOST_TEST(Y[0][1][1] == -1.0 / 2.0 * 2.0 * X[0][1][0] * X[0][1][0] - + 2.0 * test_in[0] * X[0][1][1], + tt::tolerance(tol)); + BOOST_TEST(Y[0][2][1] == -1.0 / 2.0 * 2.0 * X[0][2][0] * X[0][2][0] - + 2.0 * test_in[0] * X[0][2][1], + tt::tolerance(tol)); + + /************************** + TEST A == B + ***************************/ + + test_in[0] = 1.0; + test_in[1] = 1.0; + + // max(x^2, y^3) + test_out = std::fmin(-std::pow(test_in[0], 2), -std::pow(test_in[1], 3)); + + // A < B + X[0][0][0] = 1.0; + X[1][0][0] = 1.9; + + // A > B + X[0][1][0] = 3.0; + X[1][1][0] = 2.0; + + // A == B + X[0][2][0] = 1.0; + X[1][2][0] = 1.0; + + X[0][0][1] = -1.0; + X[1][0][1] = 1.0; + + X[0][1][1] = -2.0; + X[1][1][1] = -3.0; + + // A < B + X[0][2][1] = 1.0; + X[1][2][1] = 2.0; + + hov_forward(tag, dim_out, dim_in, degree, num_dirs, test_in.data(), X, + out.data(), Y); + BOOST_TEST(out[0] == test_out, tt::tolerance(tol)); + + // A < B + BOOST_TEST(Y[0][0][0] == -3 * std::pow(test_in[1], 2) * X[1][0][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][0][1] == + -1.0 / 2.0 * 6.0 * test_in[1] * X[1][0][0] * X[1][0][0] - + 3.0 * std::pow(test_in[1], 2.0) * X[1][0][1], + tt::tolerance(tol)); + + // A < B + BOOST_TEST(Y[0][1][0] == -2 * test_in[0] * X[0][1][0], tt::tolerance(tol)); + BOOST_TEST(Y[0][1][1] == -1.0 / 2.0 * 2.0 * X[0][1][0] * X[0][1][0] - + 2.0 * test_in[0] * X[0][1][1], + tt::tolerance(tol)); + + // A == B, A < B + BOOST_TEST(Y[0][2][0] == -3 * std::pow(test_in[1], 2) * X[1][2][0], + tt::tolerance(tol)); + BOOST_TEST(Y[0][2][1] == + -1.0 / 2.0 * 6.0 * test_in[1] * X[1][2][0] * X[1][2][0] - + 3.0 * std::pow(test_in[1], 2.0) * X[1][2][1], + tt::tolerance(tol)); + + myfree3(X); + myfree3(Y); +} BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/ADOL-C/src/uni5_for.c b/ADOL-C/src/uni5_for.c index 10c73200..a8699061 100644 --- a/ADOL-C/src/uni5_for.c +++ b/ADOL-C/src/uni5_for.c @@ -4215,10 +4215,8 @@ int hov_forward( FOR_0_LE_l_LT_p { Targ = Tqo; - if (Targ == - NULL) /* e.g. dp_T0[arg1] == - dp_T0[arg2] */ - { + /* e.g. dp_T0[arg1] == dp_T0[arg2] */ + if (Targ == NULL) { Targ1OP = Targ1; Targ2OP = Targ2; FOR_0_LE_i_LT_k { @@ -4232,9 +4230,10 @@ int hov_forward( VEC_INC(Targ1, k - i) VEC_INC(Targ2, k - i) BREAK_FOR_I + } else { + Targ1++; + Targ2++; } - Targ1++; - Targ2++; } if (Targ == NULL) /* e.g. both are equal */ Targ = Targ1OP;