From af0e27c100e2f9bed08bf7157200d64a5b24d4fb Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 17 Dec 2024 17:09:54 +0100 Subject: [PATCH 01/18] [fnc] updated AnalyticFunction (EvalMode, real_eval()) --- python/codac/core/__init__.py | 12 +-- python/src/core/codac2_py_core.cpp | 7 ++ .../analytic/codac2_py_AnalyticFunction.h | 36 ++++++- src/core/contractors/codac2_CtcProj.h | 1 + .../analytic/codac2_AnalyticFunction.h | 95 ++++++++++--------- src/core/separators/codac2_SepProj.h | 1 + .../trajectory/codac2_AnalyticTrajectory.h | 2 +- .../trajectory/codac2_SampledTrajectory.h | 13 ++- .../codac2_tests_AnalyticFunction.cpp | 32 +++---- .../analytic/codac2_tests_AnalyticFunction.py | 16 ++-- .../codac2_tests_AnalyticTrajectory.cpp | 2 +- .../codac2_tests_AnalyticTrajectory.py | 2 +- 12 files changed, 134 insertions(+), 85 deletions(-) diff --git a/python/codac/core/__init__.py b/python/codac/core/__init__.py index 4eeab90e..1c9cd220 100644 --- a/python/codac/core/__init__.py +++ b/python/codac/core/__init__.py @@ -28,14 +28,14 @@ def __init__(self, args, e): def input_size(self): return self.f.input_size() - def eval(self,*args): - return self.f.eval(*args) + def real_eval(self,*args): + return self.f.real_eval(*args) - def natural_eval(self,*args): - return self.f.natural_eval(*args) + def eval(self,m,*args): + return self.f.eval(m,*args) - def centered_eval(self,*args): - return self.f.centered_eval(*args) + def eval(self,*args): + return self.f.eval(*args) def diff(self,*args): return self.f.diff(*args) diff --git a/python/src/core/codac2_py_core.cpp b/python/src/core/codac2_py_core.cpp index 5176b48d..04a1a0f7 100644 --- a/python/src/core/codac2_py_core.cpp +++ b/python/src/core/codac2_py_core.cpp @@ -185,6 +185,13 @@ PYBIND11_MODULE(_core, m) export_Subpaving(m); // function + py::enum_(m, "EvalMode") + .value("NATURAL", EvalMode::NATURAL) + .value("CENTERED", EvalMode::CENTERED) + .value("DEFAULT", EvalMode::DEFAULT) + .def(py::self | py::self, EVALMODE_OPERATOROR_EVALMODE_EVALMODE) + ; + export_ExprWrapperBase(m); export_ScalarExpr(m); export_VectorExpr(m); diff --git a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h index 9dd8c75b..dc4e5700 100644 --- a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h @@ -25,6 +25,38 @@ using namespace codac2; namespace py = pybind11; using namespace pybind11::literals; +#define bind_mode_(exported, op_name, op, doc) \ + \ + exported \ + \ + /* Several cases of scalar inputs */ \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m) { return f.op(m); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1) { return f.op(m,x1); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2) { return f.op(m,x1,x2); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2, I x3) { return f.op(m,x1,x2,x3); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2, I x3, I x4) { return f.op(m,x1,x2,x3,x4); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2, I x3, I x4, I x5) { return f.op(m,x1,x2,x3,x4,x5); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2, I x3, I x4, I x5, I x6) { return f.op(m,x1,x2,x3,x4,x5,x6); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2, I x3, I x4, I x5, I x6, I x7) { return f.op(m,x1,x2,x3,x4,x5,x6,x7); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2, I x3, I x4, I x5, I x6, I x7, I x8) { return f.op(m,x1,x2,x3,x4,x5,x6,x7,x8); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2, I x3, I x4, I x5, I x6, I x7, I x8, I x9) { return f.op(m,x1,x2,x3,x4,x5,x6,x7,x8,x9); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, I x1, I x2, I x3, I x4, I x5, I x6, I x7, I x8, I x9, I x10) { return f.op(m,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10); }, doc) \ + \ + /* Several cases of vector inputs */ \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m) { return f.op(m); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1) { return f.op(m,x1); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2) { return f.op(m,x1,x2); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2, IV x3) { return f.op(m,x1,x2,x3); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2, IV x3, IV x4) { return f.op(m,x1,x2,x3,x4); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2, IV x3, IV x4, IV x5) { return f.op(m,x1,x2,x3,x4,x5); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2, IV x3, IV x4, IV x5, IV x6) { return f.op(m,x1,x2,x3,x4,x5,x6); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2, IV x3, IV x4, IV x5, IV x6, IV x7) { return f.op(m,x1,x2,x3,x4,x5,x6,x7); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2, IV x3, IV x4, IV x5, IV x6, IV x7, IV x8) { return f.op(m,x1,x2,x3,x4,x5,x6,x7,x8); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2, IV x3, IV x4, IV x5, IV x6, IV x7, IV x8, IV x9) { return f.op(m,x1,x2,x3,x4,x5,x6,x7,x8,x9); }, doc) \ + .def(op_name, [](AnalyticFunction& f, const EvalMode& m, IV x1, IV x2, IV x3, IV x4, IV x5, IV x6, IV x7, IV x8, IV x9, IV x10) { return f.op(m,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10); }, doc) \ + \ + ; \ + #define bind_(exported, op_name, op, doc) \ \ exported \ @@ -103,9 +135,9 @@ void export_AnalyticFunction(py::module& m, const std::string& export_name) using I = const Interval&; using IV = const IntervalVector&; + bind_(exported, "real_eval", real_eval, AUTO_ANALYTICFUNCTION_T_REAL_EVAL_CONST_ARGS_REF_VARIADIC_CONST); + bind_mode_(exported, "eval", eval, T_DOMAIN_ANALYTICFUNCTION_T_EVAL_CONST_ARGS_REF_VARIADIC_CONST); bind_(exported, "eval", eval, T_DOMAIN_ANALYTICFUNCTION_T_EVAL_CONST_ARGS_REF_VARIADIC_CONST); - bind_(exported, "natural_eval", natural_eval, T_DOMAIN_ANALYTICFUNCTION_T_NATURAL_EVAL_CONST_ARGS_REF_VARIADIC_CONST); - bind_(exported, "centered_eval", centered_eval, T_DOMAIN_ANALYTICFUNCTION_T_CENTERED_EVAL_CONST_ARGS_REF_VARIADIC_CONST); bind_(exported, "diff", diff, AUTO_ANALYTICFUNCTION_T_DIFF_CONST_ARGS_REF_VARIADIC_CONST); exported diff --git a/src/core/contractors/codac2_CtcProj.h b/src/core/contractors/codac2_CtcProj.h index 00dff8a3..1515d10e 100644 --- a/src/core/contractors/codac2_CtcProj.h +++ b/src/core/contractors/codac2_CtcProj.h @@ -35,6 +35,7 @@ namespace codac2 assert_release(*min_element(_xi.begin(),_xi.end()) >= 0); assert_release(*max_element(_xi.begin(),_xi.end()) < size_of(c)); assert_release(size_of(c) >= (Index)_xi.size() && "cannot compute a projection of a set into a superset"); + assert_release(y.is_bisectable()); assert_release(default_eps > 0.); } diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index 23a4aae5..31099e43 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -19,17 +19,18 @@ namespace codac2 { - enum class EvaluationMode + enum class EvalMode { NATURAL = 0x01, - CENTERED = 0x02 + CENTERED = 0x02, + DEFAULT = 0x03 // corresponds to (NATURAL|CENTERED) }; - inline EvaluationMode operator&(EvaluationMode a, EvaluationMode b) - { return static_cast(static_cast(a) & static_cast(b)); } + inline EvalMode operator&(EvalMode a, EvalMode b) + { return static_cast(static_cast(a) & static_cast(b)); } - inline EvaluationMode operator|(EvaluationMode a, EvaluationMode b) - { return static_cast(static_cast(a) | static_cast(b)); } + inline EvalMode operator|(EvalMode a, EvalMode b) + { return static_cast(static_cast(a) | static_cast(b)); } template requires std::is_base_of_v @@ -53,56 +54,60 @@ namespace codac2 { } template - typename T::Domain eval(const EvaluationMode& m, const Args&... x) const + auto real_eval(const Args&... x) const { - switch(m) - { - case EvaluationMode::NATURAL: - return natural_eval(x...); - - case EvaluationMode::CENTERED: - return centered_eval(x...); - - default: - return eval(x...); - } + return eval(x...).mid(); } template - typename T::Domain eval(const Args&... x) const + typename T::Domain eval(const EvalMode& m, const Args&... x) const { check_valid_inputs(x...); auto x_ = eval_(x...); - if(x_.da.size() == 0) // if the centered form is not available for this expression - return natural_eval(x...); - - auto flatten_x = cart_prod(x...); - - if constexpr(std::is_same_v) - return x_.a & (x_.m + (x_.da*(flatten_x-flatten_x.mid()))[0]); - else - return x_.a & (x_.m + (x_.da*(flatten_x-flatten_x.mid())).col(0)); - } - - template - typename T::Domain natural_eval(const Args&... x) const - { - check_valid_inputs(x...); - return eval_(x...).a; + switch(m) + { + case EvalMode::NATURAL: + { + return x_.a; + } + + case EvalMode::CENTERED: + { + auto flatten_x = cart_prod(x...); + assert(x_.da.rows() == x_.a.size() && x_.da.cols() == flatten_x.size()); + + if constexpr(std::is_same_v) + return x_.m + (x_.da*(flatten_x-flatten_x.mid()))[0]; + else + return x_.m + (x_.da*(flatten_x-flatten_x.mid())).col(0); + } + + case EvalMode::DEFAULT: + default: + { + if(x_.da.size() == 0) // if the centered form is not available for this expression + return eval(EvalMode::NATURAL, x...); + + else + { + auto flatten_x = cart_prod(x...); + if constexpr(std::is_same_v) + return x_.a & (x_.m + (x_.da*(flatten_x-flatten_x.mid()))[0]); + else + { + assert(x_.da.rows() == x_.a.size() && x_.da.cols() == flatten_x.size()); + return x_.a & (x_.m + (x_.da*(flatten_x-flatten_x.mid())).col(0)); + } + } + } + } } template - typename T::Domain centered_eval(const Args&... x) const + typename T::Domain eval(const Args&... x) const { - check_valid_inputs(x...); - auto x_ = eval_(x...); - auto flatten_x = cart_prod(x...); - - if constexpr(std::is_same_v) - return x_.m + (x_.da*(flatten_x-flatten_x.mid()))[0]; - else - return x_.m + (x_.da*(flatten_x-flatten_x.mid())).col(0); + return eval(EvalMode::NATURAL | EvalMode::CENTERED, x...); } template @@ -122,7 +127,7 @@ namespace codac2 // A dump evaluation is performed to estimate the dimension // of the image of this function. A natural evaluation is assumed // to be faster. - return natural_eval(IntervalVector(this->input_size())).size(); + return eval(EvalMode::NATURAL, IntervalVector(this->input_size())).size(); } else diff --git a/src/core/separators/codac2_SepProj.h b/src/core/separators/codac2_SepProj.h index c7dfa359..33bef843 100644 --- a/src/core/separators/codac2_SepProj.h +++ b/src/core/separators/codac2_SepProj.h @@ -36,6 +36,7 @@ namespace codac2 assert_release(*min_element(_xi.begin(),_xi.end()) >= 0); assert_release(*max_element(_xi.begin(),_xi.end()) < size_of(s)); assert_release(size_of(s) >= (Index)_xi.size() && "cannot compute a projection of a set into a superset"); + assert_release(y.is_bisectable()); assert_release(default_eps > 0.); } diff --git a/src/core/trajectory/codac2_AnalyticTrajectory.h b/src/core/trajectory/codac2_AnalyticTrajectory.h index 126107df..b0b8f5ad 100644 --- a/src/core/trajectory/codac2_AnalyticTrajectory.h +++ b/src/core/trajectory/codac2_AnalyticTrajectory.h @@ -56,7 +56,7 @@ namespace codac2 { if(!this->tdomain().contains(t)) return this->nan_value(); - return AnalyticFunction::eval(t).mid(); + return AnalyticFunction::real_eval(t); } virtual typename Wrapper::Domain operator()(const Interval& t) const diff --git a/src/core/trajectory/codac2_SampledTrajectory.h b/src/core/trajectory/codac2_SampledTrajectory.h index 52c5b807..f39ab82d 100644 --- a/src/core/trajectory/codac2_SampledTrajectory.h +++ b/src/core/trajectory/codac2_SampledTrajectory.h @@ -115,11 +115,14 @@ namespace codac2 if(!this->tdomain().is_superset(t)) return hull.init(Interval(-oo,oo)); - hull.set_empty(); - for(auto it = this->lower_bound(t.lb()) ; it != this->upper_bound(t.ub()) ; it++) - hull |= it->second; - hull |= (*this)(t.ub()); - return hull; + else + { + hull = (*this)(t.lb()); + for(auto it = this->lower_bound(t.lb()) ; it != this->upper_bound(t.ub()) ; it++) + hull |= it->second; + hull |= (*this)(t.ub()); + return hull; + } } virtual SampledTrajectory sampled(double dt) const diff --git a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp index cc09983c..8fabf900 100644 --- a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp +++ b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp @@ -18,10 +18,10 @@ using namespace codac2; TEST_CASE("AnalyticFunction") { - std::array modes { - EvaluationMode::NATURAL, - EvaluationMode::CENTERED, - EvaluationMode::NATURAL | EvaluationMode::NATURAL + std::array modes { + EvalMode::NATURAL, + EvalMode::CENTERED, + EvalMode::NATURAL | EvalMode::NATURAL }; for(const auto& m : modes) // try all available evaluation modes @@ -114,7 +114,7 @@ TEST_CASE("AnalyticFunction") // .def("__mul__", {}(const ScalarVar& e1, const VectorVar& e2); CHECK(AnalyticFunction({v1,v2}, v1[0]*v2).eval(m, Vector({5.,10.}),IntervalVector({3,3})) == Vector({15,15})); // .def("__mul__", {}(const ScalarVar& e1, const IntervalVector& e2); - CHECK(AnalyticFunction({x1}, x1*IntervalVector({{-2,3},{0,1}})).centered_eval(5.) == IntervalVector({{-10,15},{0,5}})); + CHECK(AnalyticFunction({x1}, x1*IntervalVector({{-2,3},{0,1}})).eval(EvalMode::CENTERED,5.) == IntervalVector({{-10,15},{0,5}})); // .def("__truediv__", {}(const ScalarVar& e1, const ScalarVar& e2); CHECK(Approx(AnalyticFunction({x1,x2}, x1/x2).eval(m, 1.,10.)) == 0.1); // .def("__truediv__", {}(const ScalarVar& e1, const Interval& e2); @@ -195,19 +195,19 @@ TEST_CASE("AnalyticFunction") //.def("__pos__", {}(const VectorExpr& e1); CHECK(Approx(AnalyticFunction({v1}, +(v1+v1)).eval(m, IntervalVector({{0.},{-oo,5}}))) == - (m == EvaluationMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-oo,10}}))); + (m == EvalMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-oo,10}}))); //.def(py::self + py::self); CHECK(Approx(AnalyticFunction({v1}, v1+v1).eval(m, IntervalVector({{0.},{-oo,5}}))) == - (m == EvaluationMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-oo,10}}))); + (m == EvalMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-oo,10}}))); //.def("__radd__", {}(const VectorExpr& e1, const VectorVar& e2); CHECK(Approx(AnalyticFunction({v1}, (v1+v1)+v1).eval(m, IntervalVector({{0.},{-oo,5}}))) == - (m == EvaluationMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-oo,15}}))); + (m == EvalMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-oo,15}}))); //.def("__radd__", {}(const VectorExpr& e1, const IntervalVector& e2); CHECK(Approx(AnalyticFunction({v1}, v1+(v1+v1)).eval(m, IntervalVector({{0.},{-oo,5}}))) == - (m == EvaluationMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-oo,15}}))); + (m == EvalMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-oo,15}}))); //.def(- py::self); CHECK(Approx(AnalyticFunction({v1}, -(v1+v1)).eval(m, IntervalVector({{0.},{-oo,5}}))) == - (m == EvaluationMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-10,oo}}))); + (m == EvalMode::CENTERED ? IntervalVector({{0.},{-oo,oo}}) : IntervalVector({{0.},{-10,oo}}))); //.def(py::self - py::self); CHECK(Approx(AnalyticFunction({v1,v2}, (v1-v2)).eval(m, IntervalVector({2,3}),Vector({1,5}))) == IntervalVector({1,-2})); //.def("__sub__", {}(const VectorExpr& e1, const VectorVar& e2); @@ -256,8 +256,8 @@ TEST_CASE("AnalyticFunction") { ScalarVar x; AnalyticFunction f({x}, x-x); - CHECK(f.natural_eval(Interval(-1,1)) == Interval(-2,2)); - CHECK(f.centered_eval(Interval(-1,1)) == Interval(0)); + CHECK(f.eval(EvalMode::NATURAL,Interval(-1,1)) == Interval(-2,2)); + CHECK(f.eval(EvalMode::CENTERED,Interval(-1,1)) == Interval(0)); CHECK(f.eval(Interval(-1,1)) == Interval(0)); } @@ -271,13 +271,13 @@ TEST_CASE("AnalyticFunction") IntervalVector a(4); a = IntervalVector({1,2,3,4}); - CHECK(g.natural_eval(a) == 14); - CHECK(g.centered_eval(a) == 14); + CHECK(g.eval(EvalMode::NATURAL,a) == 14); + CHECK(g.eval(EvalMode::CENTERED,a) == 14); CHECK(g.eval(a) == 14); a = IntervalVector({0,2,5,4}); - CHECK(g.natural_eval(a) == 20); - CHECK(g.centered_eval(a) == 20); + CHECK(g.eval(EvalMode::NATURAL,a) == 20); + CHECK(g.eval(EvalMode::CENTERED,a) == 20); CHECK(g.eval(a) == 20); } } \ No newline at end of file diff --git a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py index 2dc92337..e27da09b 100644 --- a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py +++ b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py @@ -34,10 +34,10 @@ def invalid_function(): def test_eval(f,*args): if(i == 0): # natural - return f.natural_eval(*args) + return f.eval(EvalMode.NATURAL,*args) elif(i == 1): # centered - return f.centered_eval(*args) + return f.eval(EvalMode.CENTERED,*args) else: # centered and natural return f.eval(*args) @@ -232,8 +232,8 @@ def test_eval(f,*args): # Evaluation modes x = ScalarVar() f = AnalyticFunction([x], x-x) - self.assertTrue(f.natural_eval(Interval(-1,1)) == Interval(-2,2)) - self.assertTrue(f.centered_eval(Interval(-1,1)) == Interval(0)) + self.assertTrue(f.eval(EvalMode.NATURAL,Interval(-1,1)) == Interval(-2,2)) + self.assertTrue(f.eval(EvalMode.CENTERED,Interval(-1,1)) == Interval(0)) self.assertTrue(f.eval(Interval(-1,1)) == Interval(0)) # Subvector on variables @@ -245,13 +245,13 @@ def test_eval(f,*args): a = IntervalVector(4) a = IntervalVector([[1],[2],[3],[4]]) - self.assertTrue(g.natural_eval(a) == 14) - self.assertTrue(g.centered_eval(a) == 14) + self.assertTrue(g.eval(EvalMode.NATURAL,a) == 14) + self.assertTrue(g.eval(EvalMode.CENTERED,a) == 14) self.assertTrue(g.eval(a) == 14) a = IntervalVector([[0],[2],[5],[4]]) - self.assertTrue(g.natural_eval(a) == 20) - self.assertTrue(g.centered_eval(a) == 20) + self.assertTrue(g.eval(EvalMode.NATURAL,a) == 20) + self.assertTrue(g.eval(EvalMode.CENTERED,a) == 20) self.assertTrue(g.eval(a) == 20) if __name__ == '__main__': diff --git a/tests/core/trajectory/codac2_tests_AnalyticTrajectory.cpp b/tests/core/trajectory/codac2_tests_AnalyticTrajectory.cpp index 2fcf8b0f..2853c2ab 100644 --- a/tests/core/trajectory/codac2_tests_AnalyticTrajectory.cpp +++ b/tests/core/trajectory/codac2_tests_AnalyticTrajectory.cpp @@ -50,7 +50,7 @@ TEST_CASE("AnalyticTrajectory") CHECK(Approx(sampled_traj(9.),1e-2) == 81.); // Testing primitive computation from analytic trajectory - double x0 = f.eval(-1).mid(); // == 1. + double x0 = f.real_eval(-1); // == 1. auto sampled_prim_traj = traj.primitive(x0,0.01); CHECK(sampled_prim_traj.tdomain() == Interval(-1,10)); CHECK(Approx(sampled_prim_traj.codomain(),4e-1) == Interval(prim_value(0),prim_value(10.))); diff --git a/tests/core/trajectory/codac2_tests_AnalyticTrajectory.py b/tests/core/trajectory/codac2_tests_AnalyticTrajectory.py index c4d76672..2e1583a7 100644 --- a/tests/core/trajectory/codac2_tests_AnalyticTrajectory.py +++ b/tests/core/trajectory/codac2_tests_AnalyticTrajectory.py @@ -48,7 +48,7 @@ def tests_AnalyticTrajectory(self): self.assertTrue(Approx(sampled_traj(9.),1e-2) == 81.) # Testing primitive computation from analytic trajectory - x0 = f.eval(-1).mid() # == 1. + x0 = f.real_eval(-1) # == 1. sampled_prim_traj = traj.primitive(x0,0.01) self.assertTrue(sampled_prim_traj.tdomain() == Interval(-1,10)) self.assertTrue(Approx(sampled_prim_traj.codomain(),4e-1) == Interval(prim_value(0),prim_value(10.))) From ffebe251ac1ac0aad9b69cfd9a026764696aec86 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Thu, 19 Dec 2024 08:21:08 +0100 Subject: [PATCH 02/18] [fnc] (Sampled)Trajectory can now be involved in analytic expressions --- src/core/CMakeLists.txt | 2 + .../analytic/codac2_analytic_operations.h | 6 ++ .../trajectory/codac2_AnalyticTrajectory.h | 5 ++ .../trajectory/codac2_SampledTrajectory.h | 10 +++ src/core/trajectory/codac2_TrajectoryBase.h | 3 + .../trajectory/codac2_Trajectory_operator.cpp | 39 ++++++++++ .../trajectory/codac2_Trajectory_operator.h | 71 +++++++++++++++++++ 7 files changed, 136 insertions(+) create mode 100644 src/core/trajectory/codac2_Trajectory_operator.cpp create mode 100644 src/core/trajectory/codac2_Trajectory_operator.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 494c1614..8eff6558 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -159,6 +159,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_AnalyticTrajectory.h ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_SampledTrajectory.h + ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_Trajectory_operator.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_Trajectory_operator.h ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_TrajectoryBase.h ) diff --git a/src/core/functions/analytic/codac2_analytic_operations.h b/src/core/functions/analytic/codac2_analytic_operations.h index e04692f5..a1a2b0eb 100644 --- a/src/core/functions/analytic/codac2_analytic_operations.h +++ b/src/core/functions/analytic/codac2_analytic_operations.h @@ -547,6 +547,12 @@ namespace codac2 return std::make_shared>(x...); } + inline ScalarExpr_ptr + ind(Index i, const VectorExpr_ptr& x1) + { + return std::make_shared>(x1,i); + } + template inline MatrixExpr_ptr mat(const std::shared_ptr>&... x) diff --git a/src/core/trajectory/codac2_AnalyticTrajectory.h b/src/core/trajectory/codac2_AnalyticTrajectory.h index b0b8f5ad..c0699356 100644 --- a/src/core/trajectory/codac2_AnalyticTrajectory.h +++ b/src/core/trajectory/codac2_AnalyticTrajectory.h @@ -67,6 +67,11 @@ namespace codac2 return AnalyticFunction::eval(t); } + /*virtual AnalyticFunction as_function() const + { + return *this; + }*/ + protected: Interval _tdomain; diff --git a/src/core/trajectory/codac2_SampledTrajectory.h b/src/core/trajectory/codac2_SampledTrajectory.h index f39ab82d..1440f287 100644 --- a/src/core/trajectory/codac2_SampledTrajectory.h +++ b/src/core/trajectory/codac2_SampledTrajectory.h @@ -11,9 +11,12 @@ #include #include "codac2_TrajectoryBase.h" +#include "codac2_analytic_variables.h" namespace codac2 { + struct TrajectoryOp; + template class SampledTrajectory : public TrajectoryBase, public std::map { @@ -146,5 +149,12 @@ namespace codac2 return straj; } + + auto as_function() const + { + ScalarVar t; + return AnalyticFunction({t}, + std::make_shared>(*this,t)); + } }; } \ No newline at end of file diff --git a/src/core/trajectory/codac2_TrajectoryBase.h b/src/core/trajectory/codac2_TrajectoryBase.h index fd3da263..610c8808 100644 --- a/src/core/trajectory/codac2_TrajectoryBase.h +++ b/src/core/trajectory/codac2_TrajectoryBase.h @@ -11,6 +11,7 @@ #include "codac2_Interval.h" #include "codac2_Wrapper.h" +#include "codac2_AnalyticFunction.h" namespace codac2 { @@ -82,5 +83,7 @@ namespace codac2 return p; } + + //virtual AnalyticFunction::Domain> as_function() const = 0; }; } \ No newline at end of file diff --git a/src/core/trajectory/codac2_Trajectory_operator.cpp b/src/core/trajectory/codac2_Trajectory_operator.cpp new file mode 100644 index 00000000..7bfa26a8 --- /dev/null +++ b/src/core/trajectory/codac2_Trajectory_operator.cpp @@ -0,0 +1,39 @@ +/** + * codac2_Trajectory_operator.cpp + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#include "codac2_Trajectory_operator.h" + +using namespace std; +using namespace codac2; + + +IntervalVector TrajectoryOp::fwd(const SampledTrajectory& x1, const Interval& x2) +{ + return x1(x2); +} + +VectorOpValue TrajectoryOp::fwd(const SampledTrajectory& x1, const ScalarOpValue& x2) +{ + IntervalMatrix d(x1.size(),x2.da.cols()); + + return { + fwd(x1,x2.m), + fwd(x1,x2.a), + d, + x2.def_domain + }; +} + +void TrajectoryOp::bwd( + [[maybe_unused]] const SampledTrajectory& x1, + [[maybe_unused]] const IntervalVector& y, + [[maybe_unused]] Interval& x2) +{ + // todo +} \ No newline at end of file diff --git a/src/core/trajectory/codac2_Trajectory_operator.h b/src/core/trajectory/codac2_Trajectory_operator.h new file mode 100644 index 00000000..9798b978 --- /dev/null +++ b/src/core/trajectory/codac2_Trajectory_operator.h @@ -0,0 +1,71 @@ +/** + * \file codac2_Trajectory_operator.h + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#pragma once + +#include "codac2_analytic_operations.h" +#include "codac2_SampledTrajectory.h" + +namespace codac2 +{ + struct TrajectoryOp + { + static IntervalVector fwd(const SampledTrajectory& x1, const Interval& x2); + static VectorOpValue fwd(const SampledTrajectory& x1, const ScalarOpValue& x2); + static void bwd(const SampledTrajectory& x1, const IntervalVector& y, Interval& x2); + }; + + + template<> + class AnalyticOperationExpr + : public AnalyticExpr, public OperationExprBase> + { + public: + + AnalyticOperationExpr(const SampledTrajectory& x1, const std::shared_ptr>& x2) + : OperationExprBase>(x2), _x1(x1) + { } + + AnalyticOperationExpr(const AnalyticOperationExpr& e) + : OperationExprBase>(e), _x1(e._x1) + { } + + std::shared_ptr copy() const + { + return std::make_shared>(*this); + } + + void replace_expr(const ExprID& old_expr_id, const std::shared_ptr& new_expr) + { + return OperationExprBase>::replace_expr(old_expr_id, new_expr); + } + + VectorOpValue fwd_eval(ValuesMap& v, Index total_input_size) const + { + return AnalyticExpr::init_value( + v, TrajectoryOp::fwd(_x1, std::get<0>(this->_x)->fwd_eval(v, total_input_size))); + } + + void bwd_eval(ValuesMap& v) const + { + TrajectoryOp::bwd(_x1, AnalyticExpr::value(v).a, std::get<0>(this->_x)->value(v).a); + std::get<0>(this->_x)->bwd_eval(v); + } + + virtual bool belongs_to_args_list(const FunctionArgsList& args) const + { + return std::get<0>(this->_x)->belongs_to_args_list(args); + } + + protected: + + const SampledTrajectory _x1; + }; + +} \ No newline at end of file From 32ab1be07fee0e5ead0679c991d5b18286c057f5 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Thu, 19 Dec 2024 16:11:31 +0100 Subject: [PATCH 03/18] [fnc] TrajectoryBase::as_function + tests --- src/core/CMakeLists.txt | 1 - .../trajectory/codac2_AnalyticTrajectory.h | 5 -- .../trajectory/codac2_SampledTrajectory.h | 9 --- src/core/trajectory/codac2_TrajectoryBase.h | 2 +- .../trajectory/codac2_Trajectory_operator.cpp | 39 ------------ .../trajectory/codac2_Trajectory_operator.h | 62 ++++++++++++++----- .../codac2_tests_SampledTrajectory.cpp | 36 +++++++++++ 7 files changed, 85 insertions(+), 69 deletions(-) delete mode 100644 src/core/trajectory/codac2_Trajectory_operator.cpp diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 8eff6558..ba1d3fa9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -159,7 +159,6 @@ ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_AnalyticTrajectory.h ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_SampledTrajectory.h - ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_Trajectory_operator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_Trajectory_operator.h ${CMAKE_CURRENT_SOURCE_DIR}/trajectory/codac2_TrajectoryBase.h ) diff --git a/src/core/trajectory/codac2_AnalyticTrajectory.h b/src/core/trajectory/codac2_AnalyticTrajectory.h index c0699356..b0b8f5ad 100644 --- a/src/core/trajectory/codac2_AnalyticTrajectory.h +++ b/src/core/trajectory/codac2_AnalyticTrajectory.h @@ -67,11 +67,6 @@ namespace codac2 return AnalyticFunction::eval(t); } - /*virtual AnalyticFunction as_function() const - { - return *this; - }*/ - protected: Interval _tdomain; diff --git a/src/core/trajectory/codac2_SampledTrajectory.h b/src/core/trajectory/codac2_SampledTrajectory.h index 1440f287..004802ee 100644 --- a/src/core/trajectory/codac2_SampledTrajectory.h +++ b/src/core/trajectory/codac2_SampledTrajectory.h @@ -15,8 +15,6 @@ namespace codac2 { - struct TrajectoryOp; - template class SampledTrajectory : public TrajectoryBase, public std::map { @@ -149,12 +147,5 @@ namespace codac2 return straj; } - - auto as_function() const - { - ScalarVar t; - return AnalyticFunction({t}, - std::make_shared>(*this,t)); - } }; } \ No newline at end of file diff --git a/src/core/trajectory/codac2_TrajectoryBase.h b/src/core/trajectory/codac2_TrajectoryBase.h index 610c8808..a7f766cc 100644 --- a/src/core/trajectory/codac2_TrajectoryBase.h +++ b/src/core/trajectory/codac2_TrajectoryBase.h @@ -84,6 +84,6 @@ namespace codac2 return p; } - //virtual AnalyticFunction::Domain> as_function() const = 0; + AnalyticFunction::Domain> as_function() const; }; } \ No newline at end of file diff --git a/src/core/trajectory/codac2_Trajectory_operator.cpp b/src/core/trajectory/codac2_Trajectory_operator.cpp deleted file mode 100644 index 7bfa26a8..00000000 --- a/src/core/trajectory/codac2_Trajectory_operator.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/** - * codac2_Trajectory_operator.cpp - * ---------------------------------------------------------------------------- - * \date 2024 - * \author Simon Rohou, Luc Jaulin - * \copyright Copyright 2024 Codac Team - * \license GNU Lesser General Public License (LGPL) - */ - -#include "codac2_Trajectory_operator.h" - -using namespace std; -using namespace codac2; - - -IntervalVector TrajectoryOp::fwd(const SampledTrajectory& x1, const Interval& x2) -{ - return x1(x2); -} - -VectorOpValue TrajectoryOp::fwd(const SampledTrajectory& x1, const ScalarOpValue& x2) -{ - IntervalMatrix d(x1.size(),x2.da.cols()); - - return { - fwd(x1,x2.m), - fwd(x1,x2.a), - d, - x2.def_domain - }; -} - -void TrajectoryOp::bwd( - [[maybe_unused]] const SampledTrajectory& x1, - [[maybe_unused]] const IntervalVector& y, - [[maybe_unused]] Interval& x2) -{ - // todo -} \ No newline at end of file diff --git a/src/core/trajectory/codac2_Trajectory_operator.h b/src/core/trajectory/codac2_Trajectory_operator.h index 9798b978..dc71aa5f 100644 --- a/src/core/trajectory/codac2_Trajectory_operator.h +++ b/src/core/trajectory/codac2_Trajectory_operator.h @@ -14,21 +14,45 @@ namespace codac2 { + template::Domain> + requires (std::is_same_v || std::is_same_v) struct TrajectoryOp { - static IntervalVector fwd(const SampledTrajectory& x1, const Interval& x2); - static VectorOpValue fwd(const SampledTrajectory& x1, const ScalarOpValue& x2); - static void bwd(const SampledTrajectory& x1, const IntervalVector& y, Interval& x2); - }; + static D fwd(const TrajectoryBase& x1, const Interval& x2) + { + return x1(x2); + } + + static typename ArgWrapper::Domain fwd(const TrajectoryBase& x1, const ScalarOpValue& x2) + { + IntervalMatrix d(x1.size(),x2.da.cols()); + + return { + fwd(x1,x2.m), + fwd(x1,x2.a), + d, + x2.def_domain && x1.tdomain().is_superset(x2.m) + }; + } + static void bwd( + [[maybe_unused]] const TrajectoryBase& x1, + [[maybe_unused]] const D& y, + [[maybe_unused]] Interval& x2) + { + // todo + } + }; - template<> - class AnalyticOperationExpr - : public AnalyticExpr, public OperationExprBase> + template + class AnalyticOperationExpr,typename ArgWrapper::Domain,ScalarOpValue> + : public AnalyticExpr::Domain>, public OperationExprBase> { public: - AnalyticOperationExpr(const SampledTrajectory& x1, const std::shared_ptr>& x2) + using O = typename ArgWrapper::Domain; + + AnalyticOperationExpr(const TrajectoryBase& x1, const std::shared_ptr>& x2) : OperationExprBase>(x2), _x1(x1) { } @@ -38,7 +62,7 @@ namespace codac2 std::shared_ptr copy() const { - return std::make_shared>(*this); + return std::make_shared,O,ScalarOpValue>>(*this); } void replace_expr(const ExprID& old_expr_id, const std::shared_ptr& new_expr) @@ -46,15 +70,15 @@ namespace codac2 return OperationExprBase>::replace_expr(old_expr_id, new_expr); } - VectorOpValue fwd_eval(ValuesMap& v, Index total_input_size) const + O fwd_eval(ValuesMap& v, Index total_input_size) const { - return AnalyticExpr::init_value( - v, TrajectoryOp::fwd(_x1, std::get<0>(this->_x)->fwd_eval(v, total_input_size))); + return AnalyticExpr::init_value( + v, TrajectoryOp::fwd(_x1, std::get<0>(this->_x)->fwd_eval(v, total_input_size))); } void bwd_eval(ValuesMap& v) const { - TrajectoryOp::bwd(_x1, AnalyticExpr::value(v).a, std::get<0>(this->_x)->value(v).a); + TrajectoryOp::bwd(_x1, AnalyticExpr::value(v).a, std::get<0>(this->_x)->value(v).a); std::get<0>(this->_x)->bwd_eval(v); } @@ -65,7 +89,17 @@ namespace codac2 protected: - const SampledTrajectory _x1; + const TrajectoryBase& _x1; }; + template + AnalyticFunction::Domain> TrajectoryBase::as_function() const + { + ScalarVar t; + return {{t}, + std::make_shared< + AnalyticOperationExpr + , typename ArgWrapper::Domain, ScalarOpValue>>(*this,t) + }; + } } \ No newline at end of file diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp index 002e1d23..7fdbb147 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -59,4 +60,39 @@ TEST_CASE("SampledTrajectory") //DefaultView::set_window_properties({75,75},{700,700}); //DefaultView::draw_trajectory(x, Color::blue()); //DefaultView::draw_trajectory(x_sampled, Color::red()); +} + +TEST_CASE("SampledTrajectory as operator (1d case)") +{ + ScalarVar t; + AnalyticFunction f { {t}, cos(t) }; + AnalyticTrajectory analytic_traj(f, {-M_PI,M_PI}); + auto sampled_traj = analytic_traj.sampled(1e-2); + auto g = sampled_traj.as_function(); + + AnalyticFunction h { {t}, g(t) }; + + for(double t = -M_PI ; t < M_PI ; t+=1e-2) + CHECK(Approx(h.real_eval(t)) == cos(t)); +} + +TEST_CASE("SampledTrajectory as operator (nd case)") +{ + ScalarVar t; + AnalyticFunction f { + {t}, + vec(2*cos(t),sin(2*t)) + }; + + auto analytic_traj = AnalyticTrajectory(f, {0,5}); + auto sampled_traj = analytic_traj.sampled(1e-2); + auto g = sampled_traj.as_function(); + + AnalyticFunction h { + {t}, + vec(1.*ind(0,g(t)),1.*ind(1,g(t))) + }; + + for(double t = 0 ; t < 5 ; t+=1e-2) + CHECK(Approx(h.real_eval(t)) == Vector({2*cos(t),sin(2*t)})); } \ No newline at end of file From 27753351caa469b063bb1d6b072ec641b0ee1bac Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Sun, 22 Dec 2024 10:31:24 +0100 Subject: [PATCH 04/18] [fnc] operator[] on analytic expressions --- src/core/CMakeLists.txt | 1 + .../analytic/codac2_AnalyticExprWrapper.h | 33 +++++++++++++++++++ .../analytic/codac2_AnalyticFunction.h | 7 ++++ 3 files changed, 41 insertions(+) create mode 100644 src/core/functions/analytic/codac2_AnalyticExprWrapper.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ba1d3fa9..7eb3dd31 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -72,6 +72,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_values.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_variables.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticExpr.h + ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticExprWrapper.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticFunction.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/set/codac2_set_operations.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/set/codac2_set_operators.h diff --git a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h new file mode 100644 index 00000000..f2ecc381 --- /dev/null +++ b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h @@ -0,0 +1,33 @@ +/** + * \file codac2_AnalyticExprWrapper.h + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#pragma once + +#include "codac2_analytic_operations.h" +#include "codac2_analytic_variables.h" +#include "codac2_AnalyticExpr.h" +#include "codac2_AnalyticFunction.h" + +namespace codac2 +{ + template + struct AnalyticExprWrapper : public std::shared_ptr> + { + AnalyticExprWrapper(const std::shared_ptr>& e) + : std::shared_ptr>(std::dynamic_pointer_cast>(e->copy())) + { } + + template + requires std::is_same_v + inline ScalarExpr_ptr operator[](Index i) + { + return std::make_shared>(*this,i); + } + }; +} \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index 31099e43..e30e01c0 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -16,6 +16,7 @@ #include "codac2_FunctionBase.h" #include "codac2_template_tools.h" #include "codac2_analytic_operations.h" +#include "codac2_AnalyticExprWrapper.h" namespace codac2 { @@ -53,6 +54,12 @@ namespace codac2 : FunctionBase>(f) { } + template + AnalyticExprWrapper test(const X&... x) const + { + return { this->FunctionBase>::operator()(x...) }; + } + template auto real_eval(const Args&... x) const { From 32f2562f1503268c0b2347e902fdd439919d4c33 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Sun, 22 Dec 2024 14:21:32 +0100 Subject: [PATCH 05/18] [fnc] vec(...) operator can now be replaced by { ... } --- examples/01_batman/main.cpp | 16 +- examples/02_centered_form/main.cpp | 10 +- examples/02_centered_form/main_evans.cpp | 14 +- examples/02_centered_form/main_parabolas.cpp | 2 +- src/core/CMakeLists.txt | 1 + .../analytic/codac2_AnalyticExprWrapper.h | 9 +- .../analytic/codac2_AnalyticFunction.h | 22 +- .../analytic/codac2_analytic_constants.h | 4 +- .../analytic/codac2_analytic_operations.h | 419 +++++++++--------- .../analytic/codac2_analytic_variables.cpp | 86 ++++ .../analytic/codac2_analytic_variables.h | 82 +--- src/core/functions/codac2_FunctionBase.h | 9 + .../trajectory/codac2_Trajectory_operator.h | 6 +- 13 files changed, 386 insertions(+), 294 deletions(-) create mode 100644 src/core/functions/analytic/codac2_analytic_variables.cpp diff --git a/examples/01_batman/main.cpp b/examples/01_batman/main.cpp index 53fb9a17..c8c62019 100644 --- a/examples/01_batman/main.cpp +++ b/examples/01_batman/main.cpp @@ -8,13 +8,21 @@ int main() VectorVar x(2); AnalyticFunction f_half_wing { - {x}, vec(x[0],sqr(x[0]/7.)+sqr(x[1]/3.)) }; + {x}, + { x[0],sqr(x[0]/7.)+sqr(x[1]/3.) } + }; AnalyticFunction f_half_head { - {x}, vec(0.75+3*x[0]-x[1]) }; + {x}, + { 0.75+3*x[0]-x[1] } + }; AnalyticFunction f_half_neck { - {x}, vec(9-8*x[0]-x[1], (6.*sqrt(10.)/7.)+(1.5-0.5*x[0])-(6.*sqrt(10.)/14.)*sqrt(4-sqr(x[0]-1))-x[1]) }; + {x}, + { 9-8*x[0]-x[1], (6.*sqrt(10.)/7.)+(1.5-0.5*x[0])-(6.*sqrt(10.)/14.)*sqrt(4-sqr(x[0]-1))-x[1] } + }; AnalyticFunction f_half_legs { - {x}, vec(((x[0]/2)-((3*sqrt(33)-7)/112)*sqr(x[0]))-3+sqrt(1-sqr(abs(x[0]-2)-1))-x[1]) }; + {x}, + { ((x[0]/2)-((3*sqrt(33)-7)/112)*sqr(x[0]))-3+sqrt(1-sqr(abs(x[0]-2)-1))-x[1] } + }; SetFunction half_bat { { /* no arguments */ }, diff --git a/examples/02_centered_form/main.cpp b/examples/02_centered_form/main.cpp index 1755095f..749eae0d 100644 --- a/examples/02_centered_form/main.cpp +++ b/examples/02_centered_form/main.cpp @@ -9,10 +9,12 @@ using namespace codac2; int main() { VectorVar x(3); - AnalyticFunction f({x}, vec( - -sqr(x[2])+2*x[2]*sin(x[2]*x[0])+cos(x[2]*x[1]), - 2*x[2]*cos(x[2]*x[0])-sin(x[2]*x[1]) - )); + AnalyticFunction f { {x}, + { + -sqr(x[2])+2*x[2]*sin(x[2]*x[0])+cos(x[2]*x[1]), + 2*x[2]*cos(x[2]*x[0])-sin(x[2]*x[1]) + } + }; CtcInverse_ ctc(f, IntervalVector::zero(2)); draw_while_paving({{0,2},{2,4},{0,10}}, ctc, 0.004); diff --git a/examples/02_centered_form/main_evans.cpp b/examples/02_centered_form/main_evans.cpp index 1e7351b9..0311d0c5 100644 --- a/examples/02_centered_form/main_evans.cpp +++ b/examples/02_centered_form/main_evans.cpp @@ -6,12 +6,16 @@ using namespace codac2; int main() { VectorVar x(4); - AnalyticFunction f({x}, vec( - sqr(x[0])-sqr(x[1])+2*exp(-x[0]*x[2])*(x[1]*sin(x[1]*x[2])+x[0]*cos(x[1]*x[2]))+exp(-x[0]*x[3])*cos(x[1]*x[3]), - 2*x[0]*x[1]+2*exp(-x[0]*x[2])*(x[1]*cos(x[1]*x[2])-x[0]*sin(x[1]*x[2]))-exp(-x[0]*x[3])*sin(x[1]*x[3]) - )); + AnalyticFunction f { {x}, + { + sqr(x[0])-sqr(x[1])+2*exp(-x[0]*x[2])*(x[1]*sin(x[1]*x[2]) + +x[0]*cos(x[1]*x[2]))+exp(-x[0]*x[3])*cos(x[1]*x[3]), + 2*x[0]*x[1]+2*exp(-x[0]*x[2])*(x[1]*cos(x[1]*x[2]) + -x[0]*sin(x[1]*x[2]))-exp(-x[0]*x[3])*sin(x[1]*x[3]) + } + }; - CtcInverse_ ctc(f, {0.,0.}); + CtcInverse_ ctc(f, IntervalVector::zero(2)); IntervalVector x0({{-10,10},{0,20},{1,1},{2,2}}); shared_ptr g = make_shared("Evans", GraphicOutput::VIBES); diff --git a/examples/02_centered_form/main_parabolas.cpp b/examples/02_centered_form/main_parabolas.cpp index 6902f389..7a11615c 100644 --- a/examples/02_centered_form/main_parabolas.cpp +++ b/examples/02_centered_form/main_parabolas.cpp @@ -22,7 +22,7 @@ int main() ); AnalyticFunction h({a}, fa(a[0],a[1])-fb(a[2],a[3])); - CtcInverse_ ctc(h, {0.,0.,0.}); + CtcInverse_ ctc(h, IntervalVector::zero(3)); IntervalVector x0({{0,1},{0,1},{0,1},{0,1}}); draw_while_paving(x0, ctc, 0.001); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7eb3dd31..6ff50980 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -70,6 +70,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_constants.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_operations.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_values.h + ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_variables.cpp ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_variables.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticExpr.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticExprWrapper.h diff --git a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h index f2ecc381..e6e40a97 100644 --- a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h +++ b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h @@ -9,10 +9,7 @@ #pragma once -#include "codac2_analytic_operations.h" -#include "codac2_analytic_variables.h" #include "codac2_AnalyticExpr.h" -#include "codac2_AnalyticFunction.h" namespace codac2 { @@ -20,14 +17,14 @@ namespace codac2 struct AnalyticExprWrapper : public std::shared_ptr> { AnalyticExprWrapper(const std::shared_ptr>& e) - : std::shared_ptr>(std::dynamic_pointer_cast>(e->copy())) + : std::shared_ptr>(e) { } template requires std::is_same_v - inline ScalarExpr_ptr operator[](Index i) + inline AnalyticExprWrapper operator[](Index i) { - return std::make_shared>(*this,i); + return { std::make_shared>(*this,i) }; } }; } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index e30e01c0..18cb2e9f 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -32,6 +32,16 @@ namespace codac2 inline EvalMode operator|(EvalMode a, EvalMode b) { return static_cast(static_cast(a) | static_cast(b)); } + + class ScalarExprList : public AnalyticExprWrapper + { + public: + + template + ScalarExprList(const S&... y) + : AnalyticExprWrapper(vec(y...)) + { } + }; template requires std::is_base_of_v @@ -39,6 +49,13 @@ namespace codac2 { public: + AnalyticFunction(const FunctionArgsList& args, const ScalarExprList& y) + : FunctionBase>(args, y) + { + assert_release(y->belongs_to_args_list(this->args()) && + "Invalid argument: variable not present in input arguments"); + } + AnalyticFunction(const FunctionArgsList& args, const std::shared_ptr>& y) : FunctionBase>(args, y) { @@ -55,7 +72,7 @@ namespace codac2 { } template - AnalyticExprWrapper test(const X&... x) const + AnalyticExprWrapper operator()(const X&... x) const { return { this->FunctionBase>::operator()(x...) }; } @@ -226,4 +243,7 @@ namespace codac2 } }; + AnalyticFunction(const FunctionArgsList&, std::initializer_list>) -> + AnalyticFunction; + } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_constants.h b/src/core/functions/analytic/codac2_analytic_constants.h index 1dbb421c..66d8ded1 100644 --- a/src/core/functions/analytic/codac2_analytic_constants.h +++ b/src/core/functions/analytic/codac2_analytic_constants.h @@ -61,8 +61,8 @@ namespace codac2 }; template - std::shared_ptr::Domain>> const_value(const T& x) + AnalyticExprWrapper::Domain> const_value(const T& x) { - return std::make_shared::Domain>>(x); + return { std::make_shared::Domain>>(x) }; } } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_operations.h b/src/core/functions/analytic/codac2_analytic_operations.h index a1a2b0eb..4e2365b2 100644 --- a/src/core/functions/analytic/codac2_analytic_operations.h +++ b/src/core/functions/analytic/codac2_analytic_operations.h @@ -13,571 +13,572 @@ #include "codac2_AnalyticExpr.h" #include "codac2_analytic_variables.h" #include "codac2_analytic_constants.h" +#include "codac2_AnalyticExprWrapper.h" namespace codac2 { - using ScalarExpr_ptr = std::shared_ptr>; - using VectorExpr_ptr = std::shared_ptr>; - using MatrixExpr_ptr = std::shared_ptr>; + using ScalarExpr = AnalyticExprWrapper; + using VectorExpr = AnalyticExprWrapper; + using MatrixExpr = AnalyticExprWrapper; template - concept IsScalarExprOrVar = (std::is_base_of_v || std::is_base_of_v); + concept IsScalarExprOrVar = (std::is_base_of_v || std::is_base_of_v); template - concept IsVectorExprOrVar = (std::is_base_of_v || std::is_base_of_v); + concept IsVectorExprOrVar = (std::is_base_of_v || std::is_base_of_v); template - concept IsMatrixExprOrVar = (std::is_base_of_v || std::is_base_of_v); + concept IsMatrixExprOrVar = (std::is_base_of_v || std::is_base_of_v); // operator+ (unary case) - inline ScalarExpr_ptr - operator+(const ScalarExpr_ptr& x1) + inline ScalarExpr + operator+(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline VectorExpr_ptr - operator+(const VectorExpr_ptr& x1) + inline VectorExpr + operator+(const VectorExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline MatrixExpr_ptr - operator+(const MatrixExpr_ptr& x1) + inline MatrixExpr + operator+(const MatrixExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } // operator+ - inline ScalarExpr_ptr - operator+(ScalarExpr_ptr x1, ScalarExpr_ptr x2) + inline ScalarExpr + operator+(ScalarExpr x1, ScalarExpr x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } template requires (!IsScalarExprOrVar) - inline ScalarExpr_ptr - operator+(const X1& x1, ScalarExpr_ptr x2) + inline ScalarExpr + operator+(const X1& x1, ScalarExpr x2) { return operator+(const_value(x1),x2); } template requires (!IsScalarExprOrVar) - inline ScalarExpr_ptr - operator+(ScalarExpr_ptr x1, const X2& x2) + inline ScalarExpr + operator+(ScalarExpr x1, const X2& x2) { return operator+(x1, const_value(x2)); } - inline VectorExpr_ptr - operator+(VectorExpr_ptr x1, VectorExpr_ptr x2) + inline VectorExpr + operator+(VectorExpr x1, VectorExpr x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } template requires (!IsVectorExprOrVar) - inline VectorExpr_ptr - operator+(const X1& x1, VectorExpr_ptr x2) + inline VectorExpr + operator+(const X1& x1, VectorExpr x2) { return operator+(const_value(x1),x2); } template requires (!IsVectorExprOrVar) - inline VectorExpr_ptr - operator+(VectorExpr_ptr x1, const X2& x2) + inline VectorExpr + operator+(VectorExpr x1, const X2& x2) { return operator+(x1, const_value(x2)); } - inline MatrixExpr_ptr - operator+(MatrixExpr_ptr x1, MatrixExpr_ptr x2) + inline MatrixExpr + operator+(MatrixExpr x1, MatrixExpr x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } template requires (!IsMatrixExprOrVar) - inline MatrixExpr_ptr - operator+(const X1& x1, MatrixExpr_ptr x2) + inline MatrixExpr + operator+(const X1& x1, MatrixExpr x2) { return operator+(const_value(x1),x2); } template requires (!IsMatrixExprOrVar) - inline MatrixExpr_ptr - operator+(MatrixExpr_ptr x1, const X2& x2) + inline MatrixExpr + operator+(MatrixExpr x1, const X2& x2) { return operator+(x1, const_value(x2)); } // operator- (unary case) - inline ScalarExpr_ptr - operator-(const ScalarExpr_ptr& x1) + inline ScalarExpr + operator-(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline VectorExpr_ptr - operator-(const VectorExpr_ptr& x1) + inline VectorExpr + operator-(const VectorExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline MatrixExpr_ptr - operator-(const MatrixExpr_ptr& x1) + inline MatrixExpr + operator-(const MatrixExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } // operator- - inline ScalarExpr_ptr - operator-(const ScalarExpr_ptr& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + operator-(const ScalarExpr& x1, const ScalarExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } template requires (!IsScalarExprOrVar) - inline ScalarExpr_ptr - operator-(const X1& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + operator-(const X1& x1, const ScalarExpr& x2) { return operator-(const_value(x1),x2); } template requires (!IsScalarExprOrVar) - inline ScalarExpr_ptr - operator-(const ScalarExpr_ptr& x1, const X2& x2) + inline ScalarExpr + operator-(const ScalarExpr& x1, const X2& x2) { return operator-(x1, const_value(x2)); } - inline VectorExpr_ptr - operator-(const VectorExpr_ptr& x1, const VectorExpr_ptr& x2) + inline VectorExpr + operator-(const VectorExpr& x1, const VectorExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } template requires (!IsVectorExprOrVar) - inline VectorExpr_ptr - operator-(const X1& x1, const VectorExpr_ptr& x2) + inline VectorExpr + operator-(const X1& x1, const VectorExpr& x2) { return operator-(const_value(x1),x2); } template requires (!IsVectorExprOrVar) - inline VectorExpr_ptr - operator-(const VectorExpr_ptr& x1, const X2& x2) + inline VectorExpr + operator-(const VectorExpr& x1, const X2& x2) { return operator-(x1, const_value(x2)); } - inline MatrixExpr_ptr - operator-(const MatrixExpr_ptr& x1, const MatrixExpr_ptr& x2) + inline MatrixExpr + operator-(const MatrixExpr& x1, const MatrixExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } template requires (!IsMatrixExprOrVar) - inline MatrixExpr_ptr - operator-(const X1& x1, const MatrixExpr_ptr& x2) + inline MatrixExpr + operator-(const X1& x1, const MatrixExpr& x2) { return operator-(const_value(x1),x2); } template requires (!IsMatrixExprOrVar) - inline MatrixExpr_ptr - operator-(const MatrixExpr_ptr& x1, const X2& x2) + inline MatrixExpr + operator-(const MatrixExpr& x1, const X2& x2) { return operator-(x1, const_value(x2)); } // operator* - inline ScalarExpr_ptr - operator*(const ScalarExpr_ptr& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + operator*(const ScalarExpr& x1, const ScalarExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } - inline VectorExpr_ptr - operator*(const ScalarExpr_ptr& x1, const VectorExpr_ptr& x2) + inline VectorExpr + operator*(const ScalarExpr& x1, const VectorExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } - inline VectorExpr_ptr - operator*(const VectorExpr_ptr& x1, const ScalarExpr_ptr& x2) + inline VectorExpr + operator*(const VectorExpr& x1, const ScalarExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } - inline ScalarExpr_ptr - operator*(const Interval& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + operator*(const Interval& x1, const ScalarExpr& x2) { return operator*(const_value(x1),x2); } - inline ScalarExpr_ptr - operator*(const ScalarExpr_ptr& x1, const Interval& x2) + inline ScalarExpr + operator*(const ScalarExpr& x1, const Interval& x2) { return operator*(x1,const_value(x2)); } - inline VectorExpr_ptr - operator*(const Interval& x1, const VectorExpr_ptr& x2) + inline VectorExpr + operator*(const Interval& x1, const VectorExpr& x2) { return operator*(const_value(x1),x2); } - inline VectorExpr_ptr - operator*(const VectorExpr_ptr& x1, const Interval& x2) + inline VectorExpr + operator*(const VectorExpr& x1, const Interval& x2) { return operator*(x1,const_value(x2)); } - inline VectorExpr_ptr - operator*(const ScalarExpr_ptr& x1, const IntervalVector& x2) + inline VectorExpr + operator*(const ScalarExpr& x1, const IntervalVector& x2) { return operator*(x1,const_value(x2)); } - inline VectorExpr_ptr - operator*(const IntervalVector& x1, const ScalarExpr_ptr& x2) + inline VectorExpr + operator*(const IntervalVector& x1, const ScalarExpr& x2) { return operator*(const_value(x1),x2); } - inline VectorExpr_ptr - operator*(const MatrixExpr_ptr& x1, const VectorExpr_ptr& x2) + inline VectorExpr + operator*(const MatrixExpr& x1, const VectorExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } - inline VectorExpr_ptr - operator*(const MatrixExpr_ptr& x1, const IntervalVector& x2) + inline VectorExpr + operator*(const MatrixExpr& x1, const IntervalVector& x2) { - return std::make_shared>(x1,const_value(x2)); + return { std::make_shared>(x1,const_value(x2)) }; } - inline VectorExpr_ptr - operator*(const IntervalMatrix& x1, const VectorExpr_ptr& x2) + inline VectorExpr + operator*(const IntervalMatrix& x1, const VectorExpr& x2) { - return std::make_shared>(const_value(x1),x2); + return { std::make_shared>(const_value(x1),x2) }; } // operator/ - inline ScalarExpr_ptr - operator/(const ScalarExpr_ptr& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + operator/(const ScalarExpr& x1, const ScalarExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } template requires (!IsScalarExprOrVar) - inline ScalarExpr_ptr - operator/(const X1& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + operator/(const X1& x1, const ScalarExpr& x2) { return operator/(const_value(x1),x2); } template requires (!IsScalarExprOrVar) - inline ScalarExpr_ptr - operator/(const ScalarExpr_ptr& x1, const X2& x2) + inline ScalarExpr + operator/(const ScalarExpr& x1, const X2& x2) { return operator/(x1, const_value(x2)); } - inline VectorExpr_ptr - operator/(const VectorExpr_ptr& x1, const ScalarExpr_ptr& x2) + inline VectorExpr + operator/(const VectorExpr& x1, const ScalarExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } // Other operators - inline ScalarExpr_ptr - pow(const ScalarExpr_ptr& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + pow(const ScalarExpr& x1, const ScalarExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } template requires (!IsScalarExprOrVar) - inline ScalarExpr_ptr - pow(const X1& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + pow(const X1& x1, const ScalarExpr& x2) { return pow(const_value(x1),x2); } template requires (!IsScalarExprOrVar) - inline ScalarExpr_ptr - pow(const ScalarExpr_ptr& x1, const X2& x2) + inline ScalarExpr + pow(const ScalarExpr& x1, const X2& x2) { return pow(x1,const_value(x2)); } - inline ScalarExpr_ptr - sqr(const ScalarExpr_ptr& x1) + inline ScalarExpr + sqr(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - sqrt(const ScalarExpr_ptr& x1) + inline ScalarExpr + sqrt(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - exp(const ScalarExpr_ptr& x1) + inline ScalarExpr + exp(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - log(const ScalarExpr_ptr& x1) + inline ScalarExpr + log(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - cos(const ScalarExpr_ptr& x1) + inline ScalarExpr + cos(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - sin(const ScalarExpr_ptr& x1) + inline ScalarExpr + sin(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - tan(const ScalarExpr_ptr& x1) + inline ScalarExpr + tan(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - acos(const ScalarExpr_ptr& x1) + inline ScalarExpr + acos(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - asin(const ScalarExpr_ptr& x1) + inline ScalarExpr + asin(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - atan(const ScalarExpr_ptr& x1) + inline ScalarExpr + atan(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - atan2(const ScalarExpr_ptr& x1, const ScalarExpr_ptr& x2) + inline ScalarExpr + atan2(const ScalarExpr& x1, const ScalarExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } - inline ScalarExpr_ptr - cosh(const ScalarExpr_ptr& x1) + inline ScalarExpr + cosh(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - sinh(const ScalarExpr_ptr& x1) + inline ScalarExpr + sinh(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - tanh(const ScalarExpr_ptr& x1) + inline ScalarExpr + tanh(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - abs(const ScalarExpr_ptr& x1) + inline ScalarExpr + abs(const ScalarExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } // Structural operators - inline ScalarExpr_ptr _add_to_vec(const ScalarExpr_ptr& x) + inline ScalarExpr _add_to_vec(const ScalarExpr& x) { return x; } - inline ScalarExpr_ptr _add_to_vec(double x) + inline ScalarExpr _add_to_vec(double x) { return const_value(x); } template - concept IsNotScalarExpr = !std::is_base_of_v; + concept IsNotScalarExpr = !std::is_base_of_v; template requires IsNotScalarExpr - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1) { - return std::make_shared>( - _add_to_vec(x1)); + _add_to_vec(x1)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2)); + _add_to_vec(x1),_add_to_vec(x2)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3)); + _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4)); + _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5)); + _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6)); + _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7)); + _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8)); + _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8),_add_to_vec(x9)); + _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8),_add_to_vec(x9)) }; } template requires (IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr && IsNotScalarExpr) - inline VectorExpr_ptr + inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9, const X10& x10) { - return std::make_shared>( - _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8),_add_to_vec(x9),_add_to_vec(x10)); + _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8),_add_to_vec(x9),_add_to_vec(x10)) }; } // Generic variadic case, cannot handle const values (int, double) for now template - inline VectorExpr_ptr - vec(const std::shared_ptr>&... x) + inline VectorExpr + vec(const AnalyticExprWrapper&... x) { - return std::make_shared>(x...); + return { std::make_shared>(x...) }; } - inline ScalarExpr_ptr - ind(Index i, const VectorExpr_ptr& x1) + inline ScalarExpr + ind(Index i, const VectorExpr& x1) { - return std::make_shared>(x1,i); + return { std::make_shared>(x1,i) }; } template - inline MatrixExpr_ptr + inline MatrixExpr mat(const std::shared_ptr>&... x) { - return std::make_shared>( - AnalyticOperationExpr(x...)); + return { std::make_shared>( + AnalyticOperationExpr(x...)) }; } // Vectorial operations - inline ScalarExpr_ptr - det(const MatrixExpr_ptr& x1) + inline ScalarExpr + det(const MatrixExpr& x1) { - return std::make_shared>(x1); + return { std::make_shared>(x1) }; } - inline ScalarExpr_ptr - det(const VectorExpr_ptr& x1, const VectorExpr_ptr& x2) + inline ScalarExpr + det(const VectorExpr& x1, const VectorExpr& x2) { - return std::make_shared>(x1,x2); + return { std::make_shared>(x1,x2) }; } - inline ScalarExpr_ptr - det(const VectorExpr_ptr& x1, const VectorExpr_ptr& x2, const VectorExpr_ptr& x3) + inline ScalarExpr + det(const VectorExpr& x1, const VectorExpr& x2, const VectorExpr& x3) { - return std::make_shared>(x1,x2,x3); + return { std::make_shared>(x1,x2,x3) }; } } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_variables.cpp b/src/core/functions/analytic/codac2_analytic_variables.cpp new file mode 100644 index 00000000..1495e9e9 --- /dev/null +++ b/src/core/functions/analytic/codac2_analytic_variables.cpp @@ -0,0 +1,86 @@ +/** + * codac2_ExprBase.cpp + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#include "codac2_analytic_variables.h" +#include "codac2_AnalyticExprWrapper.h" + +using namespace std; +using namespace codac2; + + +// ScalarVar class + + ScalarVar::ScalarVar() + { } + + ScalarVar::ScalarVar(const ScalarVar& x) + : AnalyticVarExpr(x) + { } + + std::shared_ptr ScalarVar::arg_copy() const + { + return std::make_shared(*this); + } + + std::shared_ptr ScalarVar::copy() const + { + return std::make_shared(*this); + } + + Index ScalarVar::size() const + { + return 1; + } + + AnalyticExprWrapper ScalarVar::operator-() const + { + return { std::make_shared>(*this) }; + } + + +// VectorVar class + + VectorVar::VectorVar(Index n) + : _n(n) + { + assert_release(n > 0); + } + + VectorVar::VectorVar(const VectorVar& x) + : AnalyticVarExpr(x), _n(x._n) + { } + + std::shared_ptr VectorVar::arg_copy() const + { + return std::make_shared(*this); + } + + std::shared_ptr VectorVar::copy() const + { + return std::make_shared(*this); + } + + Index VectorVar::size() const + { + return _n; + } + + AnalyticExprWrapper VectorVar::operator[](Index i) const + { + assert_release(i >= 0 && i < _n); + return { std::make_shared>( + std::dynamic_pointer_cast>(this->copy()), i) }; + } + + AnalyticExprWrapper VectorVar::subvector(Index i, Index j) const + { + assert_release(i >= 0 && i < _n && j >= i && j < _n); + return { std::make_shared>( + std::dynamic_pointer_cast>(this->copy()), i, j) }; + } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_variables.h b/src/core/functions/analytic/codac2_analytic_variables.h index 3ea24a07..aa4bce1d 100644 --- a/src/core/functions/analytic/codac2_analytic_variables.h +++ b/src/core/functions/analytic/codac2_analytic_variables.h @@ -15,6 +15,9 @@ namespace codac2 { + template + class AnalyticExprWrapper; + template class AnalyticVarExpr : public AnalyticExpr, public VarBase { @@ -39,10 +42,16 @@ namespace codac2 void replace_expr([[maybe_unused]] const ExprID& old_expr_id, [[maybe_unused]] const std::shared_ptr& new_expr) { } + // to remove operator std::shared_ptr>() const { return std::dynamic_pointer_cast>(this->copy()); } + + operator AnalyticExprWrapper() const + { + return { std::dynamic_pointer_cast>(this->copy()) }; + } virtual bool belongs_to_args_list(const FunctionArgsList& args) const { @@ -57,76 +66,29 @@ namespace codac2 { public: - ScalarVar() - { } - - ScalarVar(const ScalarVar& x) - : AnalyticVarExpr(x) - { } - - std::shared_ptr arg_copy() const - { - return std::make_shared(*this); - } + ScalarVar(); + ScalarVar(const ScalarVar& x); - std::shared_ptr copy() const - { - return std::make_shared(*this); - } + std::shared_ptr arg_copy() const; + std::shared_ptr copy() const; + Index size() const; - Index size() const - { - return 1; - } - - std::shared_ptr> operator-() const - { - return std::make_shared>(*this); - } + AnalyticExprWrapper operator-() const; }; class VectorVar : public AnalyticVarExpr { public: - explicit VectorVar(Index n) - : _n(n) - { - assert_release(n > 0); - } + explicit VectorVar(Index n); + VectorVar(const VectorVar& x); - VectorVar(const VectorVar& x) - : AnalyticVarExpr(x), _n(x._n) - { } - - std::shared_ptr arg_copy() const - { - return std::make_shared(*this); - } - - std::shared_ptr copy() const - { - return std::make_shared(*this); - } + std::shared_ptr arg_copy() const; + std::shared_ptr copy() const; + Index size() const; - Index size() const - { - return _n; - } - - std::shared_ptr> operator[](Index i) const - { - assert_release(i >= 0 && i < _n); - return std::make_shared>( - std::dynamic_pointer_cast>(this->copy()), i); - } - - std::shared_ptr> subvector(Index i, Index j) const - { - assert_release(i >= 0 && i < _n && j >= i && j < _n); - return std::make_shared>( - std::dynamic_pointer_cast>(this->copy()), i, j); - } + AnalyticExprWrapper operator[](Index i) const; + AnalyticExprWrapper subvector(Index i, Index j) const; protected: diff --git a/src/core/functions/codac2_FunctionBase.h b/src/core/functions/codac2_FunctionBase.h index f3d4fd42..24fa453a 100644 --- a/src/core/functions/codac2_FunctionBase.h +++ b/src/core/functions/codac2_FunctionBase.h @@ -83,13 +83,22 @@ namespace codac2 return std::dynamic_pointer_cast(x->copy()); } + template + std::shared_ptr __get_copy(const AnalyticExprWrapper& x) const + { + return x->copy(); + } + template auto __get_copy(const A& x) const { if constexpr(std::is_base_of_v) return std::dynamic_pointer_cast(x.copy()); else + { + // todo: make this generic (analytic / set): return const_value(x); + } } const std::shared_ptr _y; diff --git a/src/core/trajectory/codac2_Trajectory_operator.h b/src/core/trajectory/codac2_Trajectory_operator.h index dc71aa5f..58ce6fe1 100644 --- a/src/core/trajectory/codac2_Trajectory_operator.h +++ b/src/core/trajectory/codac2_Trajectory_operator.h @@ -95,11 +95,13 @@ namespace codac2 template AnalyticFunction::Domain> TrajectoryBase::as_function() const { + using D = typename ArgWrapper::Domain; + ScalarVar t; return {{t}, - std::make_shared< + AnalyticExprWrapper(std::make_shared< AnalyticOperationExpr - , typename ArgWrapper::Domain, ScalarOpValue>>(*this,t) + , D, ScalarOpValue>>(*this,t)) }; } } \ No newline at end of file From 11e161cdd69be65c6c45d1ce25d94caf3cfb7491 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Sun, 22 Dec 2024 19:40:37 +0100 Subject: [PATCH 06/18] [fnc] revised binding with recent updates (vec, AnalyticExprWrapper, etc) --- examples/02_centered_form/main.py | 4 +- python/codac/core/__init__.py | 16 +- python/src/core/codac2_py_core.cpp | 2 - .../analytic/codac2_py_AnalyticFunction.h | 159 +++++++++++++--- .../analytic/codac2_py_ExprWrapper.h | 174 ------------------ .../codac2_py_analytic_operations.cpp | 94 +++++----- .../analytic/codac2_py_analytic_variables.cpp | 6 +- .../graphics/figures/codac2_py_Figure2D.cpp | 4 +- .../analytic/codac2_AnalyticExprWrapper.h | 4 + .../analytic/codac2_AnalyticFunction.h | 8 + .../analytic/codac2_analytic_operations.h | 8 + .../analytic/codac2_tests_AnalyticFunction.py | 14 +- 12 files changed, 230 insertions(+), 263 deletions(-) diff --git a/examples/02_centered_form/main.py b/examples/02_centered_form/main.py index 374f861d..41ff95f4 100644 --- a/examples/02_centered_form/main.py +++ b/examples/02_centered_form/main.py @@ -4,10 +4,10 @@ from codac import * x = VectorVar(3) -f = AnalyticFunction([x], vec( +f = AnalyticFunction([x], [ -sqr(x[2])+2*x[2]*sin(x[2]*x[0])+cos(x[2]*x[1]), 2*x[2]*cos(x[2]*x[0])-sin(x[2]*x[1]) -)) +]) ctc = CtcInverse(f, [0,0]) graphics.draw_while_paving([[0,2],[2,4],[0,10]], ctc, 0.004) \ No newline at end of file diff --git a/python/codac/core/__init__.py b/python/codac/core/__init__.py index 1c9cd220..6948719f 100644 --- a/python/codac/core/__init__.py +++ b/python/codac/core/__init__.py @@ -19,9 +19,17 @@ class AnalyticFunction: def __init__(self, args, e): if isinstance(e, (int,float,Interval,ScalarVar,ScalarExpr)): - self.f = AnalyticFunction_Scalar(args,e) + self.f = AnalyticFunction_Scalar(args,ScalarExpr(e)) elif isinstance(e, (Vector,IntervalVector,VectorVar,VectorExpr)): - self.f = AnalyticFunction_Vector(args,e) + self.f = AnalyticFunction_Vector(args,VectorExpr(e)) + elif isinstance(e, list): + lst=[] + for e_i in e: + if isinstance(e_i, (int,float,Interval,ScalarVar,ScalarExpr)): + lst.append(ScalarExpr(e_i)) + else: + codac_error("AnalyticFunction: invalid vectorial expression") + self.f = AnalyticFunction_Vector(args,lst) else: codac_error("AnalyticFunction: can only build functions from scalar or vector expressions") @@ -44,9 +52,9 @@ def __call__(self,*args): lst=[] for arg in args: if isinstance(arg, (int,float,Interval,ScalarVar,ScalarExpr)): - lst.append(ScalarExpr(arg).raw_copy()) + lst.append(ScalarExpr(arg)) elif isinstance(arg, (Vector,IntervalVector,VectorVar,VectorExpr)): - lst.append(VectorExpr(arg).raw_copy()) + lst.append(VectorExpr(arg)) else: codac_error("AnalyticFunction: invalid input arguments") return self.f(lst) diff --git a/python/src/core/codac2_py_core.cpp b/python/src/core/codac2_py_core.cpp index 04a1a0f7..0ec5f4fd 100644 --- a/python/src/core/codac2_py_core.cpp +++ b/python/src/core/codac2_py_core.cpp @@ -62,7 +62,6 @@ void export_PavingNode(py::module& m); void export_Subpaving(py::module& m); // functions -void export_ExprWrapperBase(py::module& m); void export_ScalarVar(py::module& m); void export_VectorVar(py::module& m); void export_expression_operations(py::module& m); @@ -192,7 +191,6 @@ PYBIND11_MODULE(_core, m) .def(py::self | py::self, EVALMODE_OPERATOROR_EVALMODE_EVALMODE) ; - export_ExprWrapperBase(m); export_ScalarExpr(m); export_VectorExpr(m); export_AnalyticFunction(m,"AnalyticFunction_Scalar"); diff --git a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h index dc4e5700..05d3cc60 100644 --- a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h @@ -89,6 +89,52 @@ using namespace pybind11::literals; \ ; \ + +AnalyticExprWrapper pyobj_to_ScalarExpr(py::object& obj) +{ + if(py::isinstance(obj)) + return obj.cast(); + assert(false && "unable to convert py::object to ScalarExpr"); + return { nullptr }; +} + +std::shared_ptr pyobj_to_ExprBase(const py::object& obj) +{ + if(obj) + { + if(py::isinstance>(obj)) + return obj.cast>()->copy(); + + else if(py::isinstance>(obj)) + return obj.cast>()->copy(); + } + + assert_release("invalid expression"); + return nullptr; +} + +FunctionArgsList create_FunctionArgsList(const std::vector& l) +{ + FunctionArgsList args {}; + Index i = 0; + + for(const auto& li : l) + { + i++; + + if(py::isinstance(li)) + args.push_back(li.cast().arg_copy()); + + else if(py::isinstance(li)) + args.push_back(li.cast().arg_copy()); + + else + throw std::invalid_argument("Argument " + std::to_string(i) + " is invalid. Only variables are accepted."); + } + + return args; +} + template void export_AnalyticFunction(py::module& m, const std::string& export_name) { @@ -97,38 +143,107 @@ void export_AnalyticFunction(py::module& m, const std::string& export_name) exported .def(py::init( - [](const std::vector& l, const ExprWrapper& expr) + [](const std::vector& l, const AnalyticExprWrapper& expr) { - FunctionArgsList args {}; - Index i = 0; - - for(const auto& li : l) - { - i++; - - if(py::isinstance(li)) - args.push_back(li.cast().arg_copy()); - - else if(py::isinstance(li)) - args.push_back(li.cast().arg_copy()); - - else - throw std::invalid_argument("Argument " + std::to_string(i) + " is invalid. Only variables are accepted."); - } - - return std::make_unique>(args, expr.copy()); + return std::make_unique>( + create_FunctionArgsList(l), + std::dynamic_pointer_cast>(expr.get()->copy()) + ); } ), ANALYTICFUNCTION_T_ANALYTICFUNCTION_CONST_FUNCTIONARGSLIST_REF_CONST_SHARED_PTR_ANALYTICEXPR_T_REF) + ; + + if constexpr(std::is_same_v) + { + exported.def(py::init( + [](const std::vector& l, std::vector& v_expr) + { + return std::make_unique>( + create_FunctionArgsList(l), + [&]() -> VectorExpr { + switch(v_expr.size()) + { + case 1: + return vec( + pyobj_to_ScalarExpr(v_expr[0]) + ); + case 2: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]) + ); + case 3: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]), + pyobj_to_ScalarExpr(v_expr[2]) + ); + case 4: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]), + pyobj_to_ScalarExpr(v_expr[2]), pyobj_to_ScalarExpr(v_expr[3]) + ); + case 5: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]), + pyobj_to_ScalarExpr(v_expr[2]), pyobj_to_ScalarExpr(v_expr[3]), + pyobj_to_ScalarExpr(v_expr[4]) + ); + case 6: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]), + pyobj_to_ScalarExpr(v_expr[2]), pyobj_to_ScalarExpr(v_expr[3]), + pyobj_to_ScalarExpr(v_expr[4]), pyobj_to_ScalarExpr(v_expr[5]) + ); + case 7: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]), + pyobj_to_ScalarExpr(v_expr[2]), pyobj_to_ScalarExpr(v_expr[3]), + pyobj_to_ScalarExpr(v_expr[4]), pyobj_to_ScalarExpr(v_expr[5]), + pyobj_to_ScalarExpr(v_expr[6]) + ); + case 8: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]), + pyobj_to_ScalarExpr(v_expr[2]), pyobj_to_ScalarExpr(v_expr[3]), + pyobj_to_ScalarExpr(v_expr[4]), pyobj_to_ScalarExpr(v_expr[5]), + pyobj_to_ScalarExpr(v_expr[6]), pyobj_to_ScalarExpr(v_expr[7]) + ); + case 9: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]), + pyobj_to_ScalarExpr(v_expr[2]), pyobj_to_ScalarExpr(v_expr[3]), + pyobj_to_ScalarExpr(v_expr[4]), pyobj_to_ScalarExpr(v_expr[5]), + pyobj_to_ScalarExpr(v_expr[6]), pyobj_to_ScalarExpr(v_expr[7]), + pyobj_to_ScalarExpr(v_expr[8]) + ); + case 10: + return vec( + pyobj_to_ScalarExpr(v_expr[0]), pyobj_to_ScalarExpr(v_expr[1]), + pyobj_to_ScalarExpr(v_expr[2]), pyobj_to_ScalarExpr(v_expr[3]), + pyobj_to_ScalarExpr(v_expr[4]), pyobj_to_ScalarExpr(v_expr[5]), + pyobj_to_ScalarExpr(v_expr[6]), pyobj_to_ScalarExpr(v_expr[7]), + pyobj_to_ScalarExpr(v_expr[8]), pyobj_to_ScalarExpr(v_expr[9]) + ); + default: + assert_release("cannot create AnalyticFunction with provided vector arguments"); + return { nullptr }; + } + }() + ); + } + ), ANALYTICFUNCTION_T_ANALYTICFUNCTION_CONST_FUNCTIONARGSLIST_REF_CONST_SCALAREXPRLIST_REF); + } + + exported .def("input_size", &AnalyticFunction::input_size, INDEX_FUNCTIONBASE_E_INPUT_SIZE_CONST) - .def("__call__", [](const AnalyticFunction& f, const std::vector& x) + .def("__call__", [](const AnalyticFunction& f, py::list& x) { std::vector> v(x.size()); for(size_t i = 0 ; i < x.size() ; i++) - v[i] = x[i].eb->copy(); - return ExprWrapper(std::dynamic_pointer_cast>(f(v)->copy())); + v[i] = pyobj_to_ExprBase(x[i]); + return AnalyticExprWrapper(std::dynamic_pointer_cast>(f(v)->copy())); }, SHARED_PTR_E_FUNCTIONBASE_E_OPERATORCALL_CONST_X_REF_VARIADIC_CONST) ; diff --git a/python/src/core/functions/analytic/codac2_py_ExprWrapper.h b/python/src/core/functions/analytic/codac2_py_ExprWrapper.h index 0bac7b35..c58bed11 100644 --- a/python/src/core/functions/analytic/codac2_py_ExprWrapper.h +++ b/python/src/core/functions/analytic/codac2_py_ExprWrapper.h @@ -23,174 +23,6 @@ using namespace codac2; namespace py = pybind11; using namespace pybind11::literals; -template -struct ExprWrapper; - -struct ExprWrapperBase -{ - ExprWrapperBase() - { } - - ExprWrapperBase(const std::shared_ptr& eb_) - : eb(eb_) - { } - - std::shared_ptr eb = nullptr; -}; - -template<> -struct ExprWrapper -{ - ExprWrapper(const Interval& e) - : e(std::dynamic_pointer_cast>(const_value(e)->copy())) - { } - - ExprWrapper(const ScalarVar& e) - : e(std::dynamic_pointer_cast>(e.copy())) - { } - - ExprWrapper(const ExprWrapper& e) - : e(std::dynamic_pointer_cast>(e.copy())) - { } - - explicit ExprWrapper(const std::shared_ptr>& e) - : e(std::dynamic_pointer_cast>(e->copy())) - { } - - std::shared_ptr> copy() const - { - return std::dynamic_pointer_cast>(e->copy()); - } - - operator std::shared_ptr>() - { - return copy(); - } - - virtual ExprWrapperBase raw_copy() const - { - return ExprWrapperBase(e->copy()); - } - - std::shared_ptr> e; -}; - -using ScalarExpr = ExprWrapper; - -// Scalar operations - -inline const ScalarExpr& operator+(const ScalarExpr& e1) -{ - return e1; -} - -inline ScalarExpr operator+(const ScalarExpr& e1, const ScalarExpr& e2) -{ - return ScalarExpr(e1.e+e2.e); -} - -inline ScalarExpr operator-(const ScalarExpr& e1) -{ - return ScalarExpr(-e1.e); -} - -inline ScalarExpr operator-(const ScalarExpr& e1, const ScalarExpr& e2) -{ - return ScalarExpr(e1.e-e2.e); -} - -inline ScalarExpr operator*(const ScalarExpr& e1, const ScalarExpr& e2) -{ - return ScalarExpr(e1.e*e2.e); -} - -inline ScalarExpr operator/(const ScalarExpr& e1, const ScalarExpr& e2) -{ - return ScalarExpr(e1.e/e2.e); -} - -template<> -struct ExprWrapper -{ - ExprWrapper(const IntervalVector& e) - : e(std::dynamic_pointer_cast>(const_value(e)->copy())) - { } - - ExprWrapper(const VectorVar& e) - : e(std::dynamic_pointer_cast>(e.copy())) - { } - - ExprWrapper(const ExprWrapper& e) - : e(std::dynamic_pointer_cast>(e.copy())) - { } - - explicit ExprWrapper(const std::shared_ptr>& e) - : e(std::dynamic_pointer_cast>(e->copy())) - { } - - std::shared_ptr> copy() const - { - return std::dynamic_pointer_cast>(e->copy()); - } - - operator std::shared_ptr>() - { - return copy(); - } - - virtual ExprWrapperBase raw_copy() const - { - return ExprWrapperBase(e->copy()); - } - - std::shared_ptr> e; -}; - -using VectorExpr = ExprWrapper; - -// Vector operations - -inline const VectorExpr& operator+(const VectorExpr& e1) -{ - return e1; -} - -inline VectorExpr operator+(const VectorExpr& e1, const VectorExpr& e2) -{ - return VectorExpr(e1.e+e2.e); -} - -inline VectorExpr operator-(const VectorExpr& e1) -{ - return VectorExpr(-e1.e); -} - -inline VectorExpr operator-(const VectorExpr& e1, const VectorExpr& e2) -{ - return VectorExpr(e1.e-e2.e); -} - -inline VectorExpr operator*(const ScalarExpr& e1, const VectorExpr& e2) -{ - return VectorExpr(e1.e*e2.e); -} - -inline VectorExpr operator*(const VectorExpr& e1, const ScalarExpr& e2) -{ - return VectorExpr(e1.e*e2.e); -} - -inline VectorExpr operator/(const VectorExpr& e1, const ScalarExpr& e2) -{ - return VectorExpr(e1.e/e2.e); -} - -inline void export_ExprWrapperBase(py::module& m) -{ - py::class_ py_wrap(m, "ExprWrapperBase"); - py_wrap .def(py::init&>()); -} - inline void export_ScalarExpr(py::module& m) { py::class_ @@ -198,12 +30,9 @@ inline void export_ScalarExpr(py::module& m) exported - .def(py::init>>()) .def(py::init()) .def(py::init()) .def(py::init()) - .def("copy", &ScalarExpr::copy) - .def("raw_copy", &ScalarExpr::raw_copy) .def("__pos__", [](const ScalarExpr& e1) { return e1; }, py::is_operator()) .def(py::self + py::self) @@ -243,12 +72,9 @@ inline void export_VectorExpr(py::module& m) exported - .def(py::init>>()) .def(py::init()) .def(py::init()) .def(py::init()) - .def("copy", &VectorExpr::copy) - .def("raw_copy", &VectorExpr::raw_copy) .def("__pos__", [](const VectorExpr& e1) { return e1; }, py::is_operator()) .def(py::self + py::self) diff --git a/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp b/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp index dc000857..52c35342 100644 --- a/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp +++ b/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp @@ -27,92 +27,92 @@ void export_expression_operations(py::module& m) { m - .def("pow", [](const ScalarExpr& e1, const ScalarExpr& e2) { return ScalarExpr(pow(e1.e,e2.e)); }, - SCALAREXPR_PTR_POW_CONST_SCALAREXPR_PTR_REF_CONST_SCALAREXPR_PTR_REF, + .def("pow", [](const ScalarExpr& e1, const ScalarExpr& e2) { return ScalarExpr(pow(e1,e2)); }, + SCALAREXPR_POW_CONST_SCALAREXPR_REF_CONST_SCALAREXPR_REF, "x1"_a, "x2"_a) - .def("pow", [](const Interval& e1, const ScalarExpr& e2) { return ScalarExpr(pow(e1,e2.e)); }, - SCALAREXPR_PTR_POW_CONST_X1_REF_CONST_SCALAREXPR_PTR_REF, + .def("pow", [](const Interval& e1, const ScalarExpr& e2) { return ScalarExpr(pow(e1,e2)); }, + SCALAREXPR_POW_CONST_X1_REF_CONST_SCALAREXPR_REF, "x1"_a, "x2"_a) - .def("pow", [](const ScalarExpr& e1, const Interval& e2) { return ScalarExpr(pow(e1.e,e2)); }, - SCALAREXPR_PTR_POW_CONST_SCALAREXPR_PTR_REF_CONST_X2_REF, + .def("pow", [](const ScalarExpr& e1, const Interval& e2) { return ScalarExpr(pow(e1,e2)); }, + SCALAREXPR_POW_CONST_SCALAREXPR_REF_CONST_X2_REF, "x1"_a, "x2"_a) - .def("sqr", [](const ScalarExpr& e1) { return ScalarExpr(sqr(e1.e)); }, - SCALAREXPR_PTR_SQR_CONST_SCALAREXPR_PTR_REF, + .def("sqr", [](const ScalarExpr& e1) { return ScalarExpr(sqr(e1)); }, + SCALAREXPR_SQR_CONST_SCALAREXPR_REF, "x1"_a) - .def("sqrt", [](const ScalarExpr& e1) { return ScalarExpr(sqrt(e1.e)); }, - SCALAREXPR_PTR_SQRT_CONST_SCALAREXPR_PTR_REF, + .def("sqrt", [](const ScalarExpr& e1) { return ScalarExpr(sqrt(e1)); }, + SCALAREXPR_SQRT_CONST_SCALAREXPR_REF, "x1"_a) - .def("exp", [](const ScalarExpr& e1) { return ScalarExpr(exp(e1.e)); }, - SCALAREXPR_PTR_EXP_CONST_SCALAREXPR_PTR_REF, + .def("exp", [](const ScalarExpr& e1) { return ScalarExpr(exp(e1)); }, + SCALAREXPR_EXP_CONST_SCALAREXPR_REF, "x1"_a) - .def("log", [](const ScalarExpr& e1) { return ScalarExpr(log(e1.e)); }, - SCALAREXPR_PTR_LOG_CONST_SCALAREXPR_PTR_REF, + .def("log", [](const ScalarExpr& e1) { return ScalarExpr(log(e1)); }, + SCALAREXPR_LOG_CONST_SCALAREXPR_REF, "x1"_a) - .def("cos", [](const ScalarExpr& e1) { return ScalarExpr(cos(e1.e)); }, - SCALAREXPR_PTR_COS_CONST_SCALAREXPR_PTR_REF, + .def("cos", [](const ScalarExpr& e1) { return ScalarExpr(cos(e1)); }, + SCALAREXPR_COS_CONST_SCALAREXPR_REF, "x1"_a) - .def("sin", [](const ScalarExpr& e1) { return ScalarExpr(sin(e1.e)); }, - SCALAREXPR_PTR_SIN_CONST_SCALAREXPR_PTR_REF, + .def("sin", [](const ScalarExpr& e1) { return ScalarExpr(sin(e1)); }, + SCALAREXPR_SIN_CONST_SCALAREXPR_REF, "x1"_a) - .def("tan", [](const ScalarExpr& e1) { return ScalarExpr(tan(e1.e)); }, - SCALAREXPR_PTR_TAN_CONST_SCALAREXPR_PTR_REF, + .def("tan", [](const ScalarExpr& e1) { return ScalarExpr(tan(e1)); }, + SCALAREXPR_TAN_CONST_SCALAREXPR_REF, "x1"_a) - .def("acos", [](const ScalarExpr& e1) { return ScalarExpr(acos(e1.e)); }, - SCALAREXPR_PTR_ACOS_CONST_SCALAREXPR_PTR_REF, + .def("acos", [](const ScalarExpr& e1) { return ScalarExpr(acos(e1)); }, + SCALAREXPR_ACOS_CONST_SCALAREXPR_REF, "x1"_a) - .def("asin", [](const ScalarExpr& e1) { return ScalarExpr(asin(e1.e)); }, - SCALAREXPR_PTR_ASIN_CONST_SCALAREXPR_PTR_REF, + .def("asin", [](const ScalarExpr& e1) { return ScalarExpr(asin(e1)); }, + SCALAREXPR_ASIN_CONST_SCALAREXPR_REF, "x1"_a) - .def("atan", [](const ScalarExpr& e1) { return ScalarExpr(atan(e1.e)); }, - SCALAREXPR_PTR_ATAN_CONST_SCALAREXPR_PTR_REF, + .def("atan", [](const ScalarExpr& e1) { return ScalarExpr(atan(e1)); }, + SCALAREXPR_ATAN_CONST_SCALAREXPR_REF, "x1"_a) - .def("atan2", [](const ScalarExpr& e1, const ScalarExpr& e2) { return ScalarExpr(atan2(e1.e,e2.e)); }, - SCALAREXPR_PTR_ATAN2_CONST_SCALAREXPR_PTR_REF_CONST_SCALAREXPR_PTR_REF, + .def("atan2", [](const ScalarExpr& e1, const ScalarExpr& e2) { return ScalarExpr(atan2(e1,e2)); }, + SCALAREXPR_ATAN2_CONST_SCALAREXPR_REF_CONST_SCALAREXPR_REF, "x1"_a, "x2"_a) - .def("cosh", [](const ScalarExpr& e1) { return ScalarExpr(cosh(e1.e)); }, - SCALAREXPR_PTR_COSH_CONST_SCALAREXPR_PTR_REF, + .def("cosh", [](const ScalarExpr& e1) { return ScalarExpr(cosh(e1)); }, + SCALAREXPR_COSH_CONST_SCALAREXPR_REF, "x1"_a) - .def("sinh", [](const ScalarExpr& e1) { return ScalarExpr(sinh(e1.e)); }, - SCALAREXPR_PTR_SINH_CONST_SCALAREXPR_PTR_REF, + .def("sinh", [](const ScalarExpr& e1) { return ScalarExpr(sinh(e1)); }, + SCALAREXPR_SINH_CONST_SCALAREXPR_REF, "x1"_a) - .def("tanh", [](const ScalarExpr& e1) { return ScalarExpr(tanh(e1.e)); }, - SCALAREXPR_PTR_TANH_CONST_SCALAREXPR_PTR_REF, + .def("tanh", [](const ScalarExpr& e1) { return ScalarExpr(tanh(e1)); }, + SCALAREXPR_TANH_CONST_SCALAREXPR_REF, "x1"_a) - .def("abs", [](const ScalarExpr& e1) { return ScalarExpr(abs(e1.e)); }, - SCALAREXPR_PTR_ABS_CONST_SCALAREXPR_PTR_REF, + .def("abs", [](const ScalarExpr& e1) { return ScalarExpr(abs(e1)); }, + SCALAREXPR_ABS_CONST_SCALAREXPR_REF, "x1"_a) ; - const char* EVAL_VEC_DOC = VECTOREXPR_PTR_VEC_CONST_SHARED_PTR_ANALYTICEXPR_X_REF_VARIADIC; + const char* EVAL_VEC_DOC = VECTOREXPR_VEC_CONST_ANALYTICEXPRWRAPPER_X_REF_VARIADIC; using S = const ScalarExpr&; - m .def("vec", [](S e1) { return VectorExpr(vec(e1.e)); }, EVAL_VEC_DOC, "x1"_a) - .def("vec", [](S e1, S e2) { return VectorExpr(vec(e1.e,e2.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a) - .def("vec", [](S e1, S e2, S e3) { return VectorExpr(vec(e1.e,e2.e,e3.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a) - .def("vec", [](S e1, S e2, S e3, S e4) { return VectorExpr(vec(e1.e,e2.e,e3.e,e4.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a) - .def("vec", [](S e1, S e2, S e3, S e4, S e5) { return VectorExpr(vec(e1.e,e2.e,e3.e,e4.e,e5.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a) - .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6) { return VectorExpr(vec(e1.e,e2.e,e3.e,e4.e,e5.e,e6.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a) - .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6, S e7) { return VectorExpr(vec(e1.e,e2.e,e3.e,e4.e,e5.e,e6.e,e7.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a,"x7"_a) - .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6, S e7, S e8) { return VectorExpr(vec(e1.e,e2.e,e3.e,e4.e,e5.e,e6.e,e7.e,e8.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a,"x7"_a,"x8"_a) - .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6, S e7, S e8, S e9) { return VectorExpr(vec(e1.e,e2.e,e3.e,e4.e,e5.e,e6.e,e7.e,e8.e,e9.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a,"x7"_a,"x8"_a,"x9"_a) - .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6, S e7, S e8, S e9, S e10) { return VectorExpr(vec(e1.e,e2.e,e3.e,e4.e,e5.e,e6.e,e7.e,e8.e,e9.e,e10.e)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a,"x7"_a,"x8"_a,"x9"_a,"x10"_a) + m .def("vec", [](S e1) { return VectorExpr(vec(e1)); }, EVAL_VEC_DOC, "x1"_a) + .def("vec", [](S e1, S e2) { return VectorExpr(vec(e1,e2)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a) + .def("vec", [](S e1, S e2, S e3) { return VectorExpr(vec(e1,e2,e3)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a) + .def("vec", [](S e1, S e2, S e3, S e4) { return VectorExpr(vec(e1,e2,e3,e4)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a) + .def("vec", [](S e1, S e2, S e3, S e4, S e5) { return VectorExpr(vec(e1,e2,e3,e4,e5)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a) + .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6) { return VectorExpr(vec(e1,e2,e3,e4,e5,e6)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a) + .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6, S e7) { return VectorExpr(vec(e1,e2,e3,e4,e5,e6,e7)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a,"x7"_a) + .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6, S e7, S e8) { return VectorExpr(vec(e1,e2,e3,e4,e5,e6,e7,e8)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a,"x7"_a,"x8"_a) + .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6, S e7, S e8, S e9) { return VectorExpr(vec(e1,e2,e3,e4,e5,e6,e7,e8,e9)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a,"x7"_a,"x8"_a,"x9"_a) + .def("vec", [](S e1, S e2, S e3, S e4, S e5, S e6, S e7, S e8, S e9, S e10) { return VectorExpr(vec(e1,e2,e3,e4,e5,e6,e7,e8,e9,e10)); }, EVAL_VEC_DOC, "x1"_a,"x2"_a,"x3"_a,"x4"_a,"x5"_a,"x6"_a,"x7"_a,"x8"_a,"x9"_a,"x10"_a) ; } \ No newline at end of file diff --git a/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp b/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp index ba7f2c7f..fa7d9773 100644 --- a/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp +++ b/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp @@ -94,13 +94,13 @@ void export_VectorVar(py::module& m) exported.def("__call__", [](const VectorVar& v, Index_type i) -> ScalarExpr { return get_item(v, i); - }, SHARED_PTR_ANALYTICEXPR_SCALAROPVALUE_VECTORVAR_OPERATORCOMPO_INDEX_CONST); + }, ANALYTICEXPRWRAPPER_SCALAROPVALUE_VECTORVAR_OPERATORCOMPO_INDEX_CONST); else exported.def("__getitem__", [](const VectorVar& v, Index_type i) -> ScalarExpr { return get_item(v, i); - }, SHARED_PTR_ANALYTICEXPR_SCALAROPVALUE_VECTORVAR_OPERATORCOMPO_INDEX_CONST); + }, ANALYTICEXPRWRAPPER_SCALAROPVALUE_VECTORVAR_OPERATORCOMPO_INDEX_CONST); exported @@ -109,7 +109,7 @@ void export_VectorVar(py::module& m) matlab::test_integer(i, j); return VectorExpr(std::dynamic_pointer_cast>( v.subvector(matlab::input_index(i),matlab::input_index(j))->copy())); - }, SHARED_PTR_ANALYTICEXPR_VECTOROPVALUE_VECTORVAR_SUBVECTOR_INDEX_INDEX_CONST) + }, ANALYTICEXPRWRAPPER_VECTOROPVALUE_VECTORVAR_SUBVECTOR_INDEX_INDEX_CONST) .def("__pos__", [](const VectorVar& e1) { return VectorExpr(VectorExpr(e1)); }, py::is_operator()) .def("__add__", [](const VectorVar& e1, const VectorVar& e2) { return VectorExpr(VectorExpr(e1) + VectorExpr(e2)); }, py::is_operator()) diff --git a/python/src/graphics/figures/codac2_py_Figure2D.cpp b/python/src/graphics/figures/codac2_py_Figure2D.cpp index f976cca2..e4898aea 100644 --- a/python/src/graphics/figures/codac2_py_Figure2D.cpp +++ b/python/src/graphics/figures/codac2_py_Figure2D.cpp @@ -126,7 +126,7 @@ void export_Figure2D(py::module& m) VOID_FIGURE2D_DRAW_ELLIPSE_CONST_VECTOR_REF_CONST_VECTOR_REF_DOUBLE_CONST_STYLEPROPERTIES_REF, "c"_a, "ab"_a, "theta"_a, "s"_a=StyleProperties()) - .def("draw_trajectory", [](Figure2D& fig, py::object x, const StyleProperties& s) + .def("draw_trajectory", [](Figure2D& fig, const py::object& x, const StyleProperties& s) { py::object x_traj = x.attr("traj"); @@ -222,7 +222,7 @@ void export_Figure2D(py::module& m) STATIC_VOID_DEFAULTVIEW_DRAW_PIE_CONST_VECTOR_REF_CONST_INTERVAL_REF_CONST_INTERVAL_REF_CONST_STYLEPROPERTIES_REF, "c"_a, "r"_a, "theta"_a, "s"_a=StyleProperties()) - .def_static("draw_trajectory", [](py::object x, const StyleProperties& s) + .def_static("draw_trajectory", [](const py::object& x, const StyleProperties& s) { py::object x_traj = x.attr("traj"); diff --git a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h index e6e40a97..14263fc7 100644 --- a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h +++ b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h @@ -20,6 +20,10 @@ namespace codac2 : std::shared_ptr>(e) { } + explicit AnalyticExprWrapper(const typename T::Domain& e) + : std::shared_ptr>(const_value(e)) + { } + template requires std::is_same_v inline AnalyticExprWrapper operator[](Index i) diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index 18cb2e9f..e98357ea 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -50,6 +50,14 @@ namespace codac2 public: AnalyticFunction(const FunctionArgsList& args, const ScalarExprList& y) + requires(std::is_same_v) + : FunctionBase>(args, y) + { + assert_release(y->belongs_to_args_list(this->args()) && + "Invalid argument: variable not present in input arguments"); + } + + AnalyticFunction(const FunctionArgsList& args, const AnalyticExprWrapper& y) : FunctionBase>(args, y) { assert_release(y->belongs_to_args_list(this->args()) && diff --git a/src/core/functions/analytic/codac2_analytic_operations.h b/src/core/functions/analytic/codac2_analytic_operations.h index 4e2365b2..077a2bc0 100644 --- a/src/core/functions/analytic/codac2_analytic_operations.h +++ b/src/core/functions/analytic/codac2_analytic_operations.h @@ -310,6 +310,14 @@ namespace codac2 return { std::make_shared>(x1,x2) }; } + template + requires (!IsScalarExprOrVar) + inline VectorExpr + operator/(const VectorExpr& x1, const X2& x2) + { + return operator/(x1, const_value(x2)); + } + // Other operators inline ScalarExpr diff --git a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py index e27da09b..92e42974 100644 --- a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py +++ b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py @@ -55,16 +55,16 @@ def test_eval(f,*args): f = AnalyticFunction([x], cos(x)) self.assertTrue(Approx(test_eval(f,Interval(0))) == 1) - f = AnalyticFunction([x], vec(x,x)) + f = AnalyticFunction([x], [x,x]) - fvec = AnalyticFunction([x], vec(x,x)) + fvec = AnalyticFunction([x], [x,x]) self.assertTrue(Approx(test_eval(f,1)) == IntervalVector([[1],[1]])) - self.assertTrue(test_eval(AnalyticFunction([], +4), ) == 4) - self.assertTrue(test_eval(AnalyticFunction([], +4.), ) == 4.) - self.assertTrue(test_eval(AnalyticFunction([], +Interval(4,5)), ) == Interval(4,5)) - self.assertTrue(test_eval(AnalyticFunction([], Vector([2,9])), ) == Vector([2,9])) - self.assertTrue(test_eval(AnalyticFunction([], IntervalVector(3)), ) == IntervalVector([[-oo,oo],[-oo,oo],[-oo,oo]])) + self.assertTrue(test_eval(AnalyticFunction([], +4)) == 4) + self.assertTrue(test_eval(AnalyticFunction([], +4.)) == 4.) + self.assertTrue(test_eval(AnalyticFunction([], +Interval(4,5))) == Interval(4,5)) + self.assertTrue(test_eval(AnalyticFunction([], Vector([2,9]))) == Vector([2,9])) + self.assertTrue(test_eval(AnalyticFunction([], IntervalVector(3))) == IntervalVector([[-oo,oo],[-oo,oo],[-oo,oo]])) x1 = ScalarVar() x2 = ScalarVar() From c08ba44b94261c214a73a9175d74f8ead4a01e79 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Sun, 22 Dec 2024 19:50:55 +0100 Subject: [PATCH 07/18] [fnc] py binding: operator[] for vector expressions --- doc/manual/index.rst | 10 +++++++++- python/src/core/CMakeLists.txt | 2 +- ...rWrapper.h => codac2_py_AnalyticExprWrapper.h} | 13 ++++++++++--- .../analytic/codac2_py_AnalyticFunction.h | 6 +++--- .../analytic/codac2_py_analytic_operations.cpp | 2 +- .../analytic/codac2_py_analytic_variables.cpp | 2 +- .../analytic/codac2_AnalyticExprWrapper.h | 15 ++++++++++++++- .../analytic/codac2_analytic_operations.h | 13 ------------- 8 files changed, 39 insertions(+), 24 deletions(-) rename python/src/core/functions/analytic/{codac2_py_ExprWrapper.h => codac2_py_AnalyticExprWrapper.h} (90%) diff --git a/doc/manual/index.rst b/doc/manual/index.rst index 460fb89b..1dc36434 100644 --- a/doc/manual/index.rst +++ b/doc/manual/index.rst @@ -13,15 +13,23 @@ Codac manual .. toctree:: :caption: User manual - :maxdepth: 3 + :maxdepth: 2 installation/index.rst intervals/index.rst linear/index.rst functions/index.rst tubes/index.rst + +.. toctree:: + :maxdepth: 3 + contractors/index.rst separators/index.rst + +.. toctree:: + :maxdepth: 2 + pavers/index.rst cn/index.rst geometry/index.rst diff --git a/python/src/core/CMakeLists.txt b/python/src/core/CMakeLists.txt index 5fb9220c..5caa3720 100644 --- a/python/src/core/CMakeLists.txt +++ b/python/src/core/CMakeLists.txt @@ -47,7 +47,7 @@ functions/analytic/codac2_py_analytic_operations.cpp functions/analytic/codac2_py_analytic_variables.cpp functions/analytic/codac2_py_AnalyticFunction.h - functions/analytic/codac2_py_ExprWrapper.h + functions/analytic/codac2_py_AnalyticExprWrapper.h geometry/codac2_py_Edge.cpp geometry/codac2_py_geometry.cpp diff --git a/python/src/core/functions/analytic/codac2_py_ExprWrapper.h b/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h similarity index 90% rename from python/src/core/functions/analytic/codac2_py_ExprWrapper.h rename to python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h index c58bed11..b130b3b6 100644 --- a/python/src/core/functions/analytic/codac2_py_ExprWrapper.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h @@ -14,10 +14,10 @@ #include #include #include +#include "codac2_AnalyticExprWrapper.h" #include "codac2_analytic_operations.h" -#include "codac2_analytic_variables.h" -#include "codac2_AnalyticExpr.h" -#include "codac2_AnalyticFunction.h" +#include "codac2_py_matlab.h" +#include "codac2_py_AnalyticExprWrapper_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py) using namespace codac2; namespace py = pybind11; @@ -76,6 +76,13 @@ inline void export_VectorExpr(py::module& m) .def(py::init()) .def(py::init()) + .def("__getitem__", [](const VectorExpr& x, Index_type index) + { + matlab::test_integer(index); + return x[matlab::input_index(index)]; + }, py::return_value_policy::reference_internal, + ANALYTICEXPRWRAPPER_SCALAROPVALUE_ANALYTICEXPRWRAPPER_T_OPERATORCOMPO_INDEX_CONST) + .def("__pos__", [](const VectorExpr& e1) { return e1; }, py::is_operator()) .def(py::self + py::self) .def("__add__", [](const VectorExpr& e1, const VectorVar& e2) { return e1+e2; }, py::is_operator()) diff --git a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h index 05d3cc60..6c776edf 100644 --- a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h @@ -19,7 +19,7 @@ #include #include "codac2_py_AnalyticFunction_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py) #include "codac2_py_FunctionBase_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py) -#include "codac2_py_ExprWrapper.h" +#include "codac2_py_AnalyticExprWrapper.h" using namespace codac2; namespace py = pybind11; @@ -90,7 +90,7 @@ using namespace pybind11::literals; ; \ -AnalyticExprWrapper pyobj_to_ScalarExpr(py::object& obj) +AnalyticExprWrapper pyobj_to_ScalarExpr(const py::object& obj) { if(py::isinstance(obj)) return obj.cast(); @@ -156,7 +156,7 @@ void export_AnalyticFunction(py::module& m, const std::string& export_name) if constexpr(std::is_same_v) { exported.def(py::init( - [](const std::vector& l, std::vector& v_expr) + [](const std::vector& l, const std::vector& v_expr) { return std::make_unique>( create_FunctionArgsList(l), diff --git a/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp b/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp index 52c35342..9706af0d 100644 --- a/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp +++ b/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp @@ -16,7 +16,7 @@ #include #include #include "codac2_py_analytic_operations_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py) -#include "codac2_py_ExprWrapper.h" +#include "codac2_py_AnalyticExprWrapper.h" using namespace codac2; namespace py = pybind11; diff --git a/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp b/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp index fa7d9773..08f15fa4 100644 --- a/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp +++ b/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp @@ -14,7 +14,7 @@ #include #include #include "codac2_py_analytic_variables_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py): -#include "codac2_py_ExprWrapper.h" +#include "codac2_py_AnalyticExprWrapper.h" #include "codac2_py_matlab.h" using namespace codac2; diff --git a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h index 14263fc7..c5049a5a 100644 --- a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h +++ b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h @@ -26,9 +26,22 @@ namespace codac2 template requires std::is_same_v - inline AnalyticExprWrapper operator[](Index i) + inline AnalyticExprWrapper operator[](Index i) const { return { std::make_shared>(*this,i) }; } }; + + using ScalarExpr = AnalyticExprWrapper; + using VectorExpr = AnalyticExprWrapper; + using MatrixExpr = AnalyticExprWrapper; + + template + concept IsScalarExprOrVar = (std::is_base_of_v || std::is_base_of_v); + + template + concept IsVectorExprOrVar = (std::is_base_of_v || std::is_base_of_v); + + template + concept IsMatrixExprOrVar = (std::is_base_of_v || std::is_base_of_v); } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_operations.h b/src/core/functions/analytic/codac2_analytic_operations.h index 077a2bc0..a8aac162 100644 --- a/src/core/functions/analytic/codac2_analytic_operations.h +++ b/src/core/functions/analytic/codac2_analytic_operations.h @@ -17,19 +17,6 @@ namespace codac2 { - using ScalarExpr = AnalyticExprWrapper; - using VectorExpr = AnalyticExprWrapper; - using MatrixExpr = AnalyticExprWrapper; - - template - concept IsScalarExprOrVar = (std::is_base_of_v || std::is_base_of_v); - - template - concept IsVectorExprOrVar = (std::is_base_of_v || std::is_base_of_v); - - template - concept IsMatrixExprOrVar = (std::is_base_of_v || std::is_base_of_v); - // operator+ (unary case) inline ScalarExpr From 0c95113c414bfb7873e5c71d0ab757907badbcab Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Thu, 26 Dec 2024 12:19:00 +0100 Subject: [PATCH 08/18] [fnc] updated functions implementation --- .../analytic/codac2_py_AnalyticExprWrapper.h | 13 +- .../analytic/codac2_py_AnalyticFunction.h | 4 +- .../codac2_py_analytic_operations.cpp | 8 - src/core/CMakeLists.txt | 1 + .../functions/analytic/codac2_AnalyticExpr.h | 12 -- .../analytic/codac2_AnalyticExprWrapper.h | 22 +- .../analytic/codac2_AnalyticFunction.h | 48 ++--- .../analytic/codac2_ScalarExprList.h | 135 +++++++++++++ .../analytic/codac2_analytic_constants.h | 2 - .../analytic/codac2_analytic_operations.h | 190 ------------------ .../analytic/codac2_analytic_variables.cpp | 11 +- .../analytic/codac2_analytic_variables.h | 13 -- src/core/functions/codac2_ExprBase.h | 1 - src/core/trajectory/codac2_TrajectoryBase.h | 1 + .../trajectory/codac2_Trajectory_operator.h | 3 +- .../codac2_tests_AnalyticFunction.cpp | 64 +++++- .../analytic/codac2_tests_AnalyticFunction.py | 42 ++++ .../codac2_tests_SampledTrajectory.cpp | 23 ++- 18 files changed, 307 insertions(+), 286 deletions(-) create mode 100644 src/core/functions/analytic/codac2_ScalarExprList.h diff --git a/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h b/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h index b130b3b6..c51485c8 100644 --- a/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h @@ -30,30 +30,28 @@ inline void export_ScalarExpr(py::module& m) exported - .def(py::init()) + .def(py::init()) + .def(py::init()) .def(py::init()) + .def(py::init()) .def(py::init()) .def("__pos__", [](const ScalarExpr& e1) { return e1; }, py::is_operator()) .def(py::self + py::self) - .def("__radd__", [](const ScalarExpr& e1, const ScalarVar& e2) { return e2+e1; }, py::is_operator()) .def("__add__", [](const ScalarExpr& e1, const Interval& e2) { return e1+e2; }, py::is_operator()) .def("__radd__", [](const ScalarExpr& e1, const Interval& e2) { return e2+e1; }, py::is_operator()) .def(- py::self) .def(py::self - py::self) - .def("__sub__", [](const ScalarExpr& e1, const ScalarVar& e2) { return e1-e2; }, py::is_operator()) .def("__sub__", [](const ScalarExpr& e1, const Interval& e2) { return e1-e2; }, py::is_operator()) .def("__rsub__", [](const ScalarExpr& e1, const Interval& e2) { return e2-e1; }, py::is_operator()) .def(py::self * py::self) - .def("__mul__", [](const ScalarExpr& e1, const ScalarVar& e2) { return e1*e2; }, py::is_operator()) .def("__mul__", [](const ScalarExpr& e1, const Interval& e2) { return e1*e2; }, py::is_operator()) .def("__rmul__", [](const ScalarExpr& e1, const Interval& e2) { return e2*e1; }, py::is_operator()) .def("__mul__", [](const ScalarExpr& e1, const VectorExpr& e2) { return e1*e2; }, py::is_operator()) .def("__truediv__", [](const ScalarExpr& e1, const ScalarExpr& e2) { return e1/e2; }, py::is_operator()) - .def("__truediv__", [](const ScalarExpr& e1, const ScalarVar& e2) { return e1/e2; }, py::is_operator()) .def("__truediv__", [](const ScalarExpr& e1, const Interval& e2) { return e1/e2; }, py::is_operator()) .def("__rtruediv__", [](const ScalarExpr& e1, const Interval& e2) { return e2/e1; }, py::is_operator()) @@ -72,8 +70,9 @@ inline void export_VectorExpr(py::module& m) exported - .def(py::init()) + .def(py::init()) .def(py::init()) + .def(py::init()) .def(py::init()) .def("__getitem__", [](const VectorExpr& x, Index_type index) @@ -85,13 +84,11 @@ inline void export_VectorExpr(py::module& m) .def("__pos__", [](const VectorExpr& e1) { return e1; }, py::is_operator()) .def(py::self + py::self) - .def("__add__", [](const VectorExpr& e1, const VectorVar& e2) { return e1+e2; }, py::is_operator()) .def("__add__", [](const VectorExpr& e1, const IntervalVector& e2) { return e1+e2; }, py::is_operator()) .def("__radd__", [](const VectorExpr& e1, const IntervalVector& e2) { return e1+e2; }, py::is_operator()) .def(- py::self) .def(py::self - py::self) - .def("__sub__", [](const VectorExpr& e1, const VectorVar& e2) { return e1-e2; }, py::is_operator()) .def("__sub__", [](const VectorExpr& e1, const IntervalVector& e2) { return e1-e2; }, py::is_operator()) .def("__rsub__", [](const VectorExpr& e1, const IntervalVector& e2) { return e2-e1; }, py::is_operator()) diff --git a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h index 6c776edf..ae636ad7 100644 --- a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h @@ -147,10 +147,10 @@ void export_AnalyticFunction(py::module& m, const std::string& export_name) { return std::make_unique>( create_FunctionArgsList(l), - std::dynamic_pointer_cast>(expr.get()->copy()) + AnalyticExprWrapper{ std::dynamic_pointer_cast>(expr.get()->copy()) } ); } - ), ANALYTICFUNCTION_T_ANALYTICFUNCTION_CONST_FUNCTIONARGSLIST_REF_CONST_SHARED_PTR_ANALYTICEXPR_T_REF) + ), ANALYTICFUNCTION_T_ANALYTICFUNCTION_CONST_FUNCTIONARGSLIST_REF_CONST_ANALYTICEXPRWRAPPER_T_REF) ; if constexpr(std::is_same_v) diff --git a/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp b/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp index 9706af0d..29ddaf39 100644 --- a/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp +++ b/python/src/core/functions/analytic/codac2_py_analytic_operations.cpp @@ -31,14 +31,6 @@ void export_expression_operations(py::module& m) SCALAREXPR_POW_CONST_SCALAREXPR_REF_CONST_SCALAREXPR_REF, "x1"_a, "x2"_a) - .def("pow", [](const Interval& e1, const ScalarExpr& e2) { return ScalarExpr(pow(e1,e2)); }, - SCALAREXPR_POW_CONST_X1_REF_CONST_SCALAREXPR_REF, - "x1"_a, "x2"_a) - - .def("pow", [](const ScalarExpr& e1, const Interval& e2) { return ScalarExpr(pow(e1,e2)); }, - SCALAREXPR_POW_CONST_SCALAREXPR_REF_CONST_X2_REF, - "x1"_a, "x2"_a) - .def("sqr", [](const ScalarExpr& e1) { return ScalarExpr(sqr(e1)); }, SCALAREXPR_SQR_CONST_SCALAREXPR_REF, "x1"_a) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 6ff50980..feb6f021 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -75,6 +75,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticExpr.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticExprWrapper.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticFunction.h + ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_ScalarExprList.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/set/codac2_set_operations.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/set/codac2_set_operators.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/set/codac2_set_variables.h diff --git a/src/core/functions/analytic/codac2_AnalyticExpr.h b/src/core/functions/analytic/codac2_AnalyticExpr.h index 134d62a2..a0bd43af 100644 --- a/src/core/functions/analytic/codac2_AnalyticExpr.h +++ b/src/core/functions/analytic/codac2_AnalyticExpr.h @@ -63,10 +63,6 @@ namespace codac2 : OperationExprBase...>(x...) { } - AnalyticOperationExpr(const AnalyticOperationExpr& e) - : OperationExprBase...>(e) - { } - std::shared_ptr copy() const { return std::make_shared>(*this); @@ -124,10 +120,6 @@ namespace codac2 : OperationExprBase>(x1), _i(i) { } - AnalyticOperationExpr(const AnalyticOperationExpr& e) - : OperationExprBase>(e), _i(e._i) - { } - std::shared_ptr copy() const { return std::make_shared>(*this); @@ -169,10 +161,6 @@ namespace codac2 : OperationExprBase>(x1), _i(i), _j(j) { } - AnalyticOperationExpr(const AnalyticOperationExpr& e) - : OperationExprBase>(e), _i(e._i), _j(e._j) - { } - std::shared_ptr copy() const { return std::make_shared>(*this); diff --git a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h index c5049a5a..972c6be2 100644 --- a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h +++ b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h @@ -10,6 +10,7 @@ #pragma once #include "codac2_AnalyticExpr.h" +#include "codac2_analytic_constants.h" namespace codac2 { @@ -19,14 +20,25 @@ namespace codac2 AnalyticExprWrapper(const std::shared_ptr>& e) : std::shared_ptr>(e) { } - - explicit AnalyticExprWrapper(const typename T::Domain& e) + + AnalyticExprWrapper(const ScalarVar& e) + requires std::is_same_v + : std::shared_ptr>({ std::dynamic_pointer_cast>(e.copy()) }) + { } + + AnalyticExprWrapper(const VectorVar& e) + requires std::is_same_v + : std::shared_ptr>({ std::dynamic_pointer_cast>(e.copy()) }) + { } + + template + AnalyticExprWrapper(const V& e) + requires std::is_same_v::Domain,T> : std::shared_ptr>(const_value(e)) { } - - template - requires std::is_same_v + inline AnalyticExprWrapper operator[](Index i) const + requires std::is_same_v { return { std::make_shared>(*this,i) }; } diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index e98357ea..dc796d6d 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -17,6 +17,7 @@ #include "codac2_template_tools.h" #include "codac2_analytic_operations.h" #include "codac2_AnalyticExprWrapper.h" +#include "codac2_ScalarExprList.h" namespace codac2 { @@ -33,16 +34,6 @@ namespace codac2 inline EvalMode operator|(EvalMode a, EvalMode b) { return static_cast(static_cast(a) | static_cast(b)); } - class ScalarExprList : public AnalyticExprWrapper - { - public: - - template - ScalarExprList(const S&... y) - : AnalyticExprWrapper(vec(y...)) - { } - }; - template requires std::is_base_of_v class AnalyticFunction : public FunctionBase> @@ -64,19 +55,8 @@ namespace codac2 "Invalid argument: variable not present in input arguments"); } - AnalyticFunction(const FunctionArgsList& args, const std::shared_ptr>& y) - : FunctionBase>(args, y) - { - assert_release(y->belongs_to_args_list(this->args()) && - "Invalid argument: variable not present in input arguments"); - } - AnalyticFunction(const FunctionArgsList& args, const AnalyticVarExpr& y) - : AnalyticFunction(args, y.operator std::shared_ptr>()) - { } - - AnalyticFunction(const AnalyticFunction& f) - : FunctionBase>(f) + : AnalyticFunction(args, { std::dynamic_pointer_cast>(y.copy()) }) { } template @@ -251,7 +231,29 @@ namespace codac2 } }; - AnalyticFunction(const FunctionArgsList&, std::initializer_list>) -> + AnalyticFunction(const FunctionArgsList&, double) -> + AnalyticFunction; + + AnalyticFunction(const FunctionArgsList&, const Interval&) -> + AnalyticFunction; + + AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> + AnalyticFunction; + + AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> + AnalyticFunction; + + AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> AnalyticFunction; + AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> + AnalyticFunction; + + AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> + AnalyticFunction; + + template + AnalyticFunction(const FunctionArgsList&, const T&) -> + AnalyticFunction::Domain>; + } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_ScalarExprList.h b/src/core/functions/analytic/codac2_ScalarExprList.h new file mode 100644 index 00000000..7ac1f630 --- /dev/null +++ b/src/core/functions/analytic/codac2_ScalarExprList.h @@ -0,0 +1,135 @@ +/** + * \file codac2_ScalarExprList.h + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#pragma once + +#include "codac2_AnalyticExprWrapper.h" + +namespace codac2 +{ + // Template parameter packs cannot be used for ScalarExprList because arguments are + // provided by std::initializer_list (see template deduction guides for AnalyticFunction) + + template + concept IsScalar = std::is_same_v || std::is_same_v || + std::is_same_v::Domain,ScalarOpValue>; + + struct ScalarExprList : public AnalyticExprWrapper + { + template + requires IsScalar + ScalarExprList(const S1& y1) + : AnalyticExprWrapper(vec(to_ScalarExpr(y1))) + { } + + template + requires IsScalar && IsScalar + ScalarExprList(const S1& y1, const S2& y2) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1),to_ScalarExpr(y2) + )) + { } + + template + requires IsScalar && IsScalar && IsScalar + ScalarExprList(const S1& y1, const S2& y2, const S3& y3) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3) + )) + { } + + template + requires IsScalar && IsScalar && IsScalar && IsScalar + ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4) + )) + { } + + template + requires IsScalar && IsScalar && IsScalar && IsScalar && IsScalar + ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5) + )) + { } + + template + requires IsScalar && IsScalar && IsScalar && IsScalar && IsScalar + && IsScalar + ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, + const S6& y6) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), + to_ScalarExpr(y6) + )) + { } + + template + requires IsScalar && IsScalar && IsScalar && IsScalar && IsScalar + && IsScalar && IsScalar + ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, + const S6& y6, const S7& y7) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), + to_ScalarExpr(y6), to_ScalarExpr(y7) + )) + { } + + template + requires IsScalar && IsScalar && IsScalar && IsScalar && IsScalar + && IsScalar && IsScalar && IsScalar + ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, + const S6& y6, const S7& y7, const S8& y8) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), + to_ScalarExpr(y6), to_ScalarExpr(y7), to_ScalarExpr(y8) + )) + { } + + template + requires IsScalar && IsScalar && IsScalar && IsScalar && IsScalar + && IsScalar && IsScalar && IsScalar && IsScalar + ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, + const S6& y6, const S7& y7, const S8& y8, const S9& y9) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), + to_ScalarExpr(y6), to_ScalarExpr(y7), to_ScalarExpr(y8), to_ScalarExpr(y9) + )) + { } + + template + requires IsScalar && IsScalar && IsScalar && IsScalar && IsScalar + && IsScalar && IsScalar && IsScalar && IsScalar && IsScalar + ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, + const S6& y6, const S7& y7, const S8& y8, const S9& y9, const S10& y10) + : AnalyticExprWrapper(vec( + to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), + to_ScalarExpr(y6), to_ScalarExpr(y7), to_ScalarExpr(y8), to_ScalarExpr(y9), to_ScalarExpr(y10) + )) + { } + + const ScalarExpr& to_ScalarExpr(const ScalarExpr& e) + { + return e; + } + + template + requires std::is_same_v::Domain,ScalarOpValue> + ScalarExpr to_ScalarExpr(const T& e) + { + return const_value(e); + } + }; +} \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_constants.h b/src/core/functions/analytic/codac2_analytic_constants.h index 66d8ded1..72cd7f1e 100644 --- a/src/core/functions/analytic/codac2_analytic_constants.h +++ b/src/core/functions/analytic/codac2_analytic_constants.h @@ -22,8 +22,6 @@ namespace codac2 : _x(x) { } - ConstValueExpr(const ConstValueExpr& e) = default; - std::shared_ptr copy() const { return std::make_shared>(*this); diff --git a/src/core/functions/analytic/codac2_analytic_operations.h b/src/core/functions/analytic/codac2_analytic_operations.h index a8aac162..0b277860 100644 --- a/src/core/functions/analytic/codac2_analytic_operations.h +++ b/src/core/functions/analytic/codac2_analytic_operations.h @@ -45,66 +45,18 @@ namespace codac2 return { std::make_shared>(x1,x2) }; } - template - requires (!IsScalarExprOrVar) - inline ScalarExpr - operator+(const X1& x1, ScalarExpr x2) - { - return operator+(const_value(x1),x2); - } - - template - requires (!IsScalarExprOrVar) - inline ScalarExpr - operator+(ScalarExpr x1, const X2& x2) - { - return operator+(x1, const_value(x2)); - } - inline VectorExpr operator+(VectorExpr x1, VectorExpr x2) { return { std::make_shared>(x1,x2) }; } - template - requires (!IsVectorExprOrVar) - inline VectorExpr - operator+(const X1& x1, VectorExpr x2) - { - return operator+(const_value(x1),x2); - } - - template - requires (!IsVectorExprOrVar) - inline VectorExpr - operator+(VectorExpr x1, const X2& x2) - { - return operator+(x1, const_value(x2)); - } - inline MatrixExpr operator+(MatrixExpr x1, MatrixExpr x2) { return { std::make_shared>(x1,x2) }; } - template - requires (!IsMatrixExprOrVar) - inline MatrixExpr - operator+(const X1& x1, MatrixExpr x2) - { - return operator+(const_value(x1),x2); - } - - template - requires (!IsMatrixExprOrVar) - inline MatrixExpr - operator+(MatrixExpr x1, const X2& x2) - { - return operator+(x1, const_value(x2)); - } - // operator- (unary case) inline ScalarExpr @@ -133,66 +85,18 @@ namespace codac2 return { std::make_shared>(x1,x2) }; } - template - requires (!IsScalarExprOrVar) - inline ScalarExpr - operator-(const X1& x1, const ScalarExpr& x2) - { - return operator-(const_value(x1),x2); - } - - template - requires (!IsScalarExprOrVar) - inline ScalarExpr - operator-(const ScalarExpr& x1, const X2& x2) - { - return operator-(x1, const_value(x2)); - } - inline VectorExpr operator-(const VectorExpr& x1, const VectorExpr& x2) { return { std::make_shared>(x1,x2) }; } - template - requires (!IsVectorExprOrVar) - inline VectorExpr - operator-(const X1& x1, const VectorExpr& x2) - { - return operator-(const_value(x1),x2); - } - - template - requires (!IsVectorExprOrVar) - inline VectorExpr - operator-(const VectorExpr& x1, const X2& x2) - { - return operator-(x1, const_value(x2)); - } - inline MatrixExpr operator-(const MatrixExpr& x1, const MatrixExpr& x2) { return { std::make_shared>(x1,x2) }; } - template - requires (!IsMatrixExprOrVar) - inline MatrixExpr - operator-(const X1& x1, const MatrixExpr& x2) - { - return operator-(const_value(x1),x2); - } - - template - requires (!IsMatrixExprOrVar) - inline MatrixExpr - operator-(const MatrixExpr& x1, const X2& x2) - { - return operator-(x1, const_value(x2)); - } - // operator* inline ScalarExpr @@ -213,60 +117,12 @@ namespace codac2 return { std::make_shared>(x1,x2) }; } - inline ScalarExpr - operator*(const Interval& x1, const ScalarExpr& x2) - { - return operator*(const_value(x1),x2); - } - - inline ScalarExpr - operator*(const ScalarExpr& x1, const Interval& x2) - { - return operator*(x1,const_value(x2)); - } - - inline VectorExpr - operator*(const Interval& x1, const VectorExpr& x2) - { - return operator*(const_value(x1),x2); - } - - inline VectorExpr - operator*(const VectorExpr& x1, const Interval& x2) - { - return operator*(x1,const_value(x2)); - } - - inline VectorExpr - operator*(const ScalarExpr& x1, const IntervalVector& x2) - { - return operator*(x1,const_value(x2)); - } - - inline VectorExpr - operator*(const IntervalVector& x1, const ScalarExpr& x2) - { - return operator*(const_value(x1),x2); - } - inline VectorExpr operator*(const MatrixExpr& x1, const VectorExpr& x2) { return { std::make_shared>(x1,x2) }; } - inline VectorExpr - operator*(const MatrixExpr& x1, const IntervalVector& x2) - { - return { std::make_shared>(x1,const_value(x2)) }; - } - - inline VectorExpr - operator*(const IntervalMatrix& x1, const VectorExpr& x2) - { - return { std::make_shared>(const_value(x1),x2) }; - } - // operator/ inline ScalarExpr @@ -274,22 +130,6 @@ namespace codac2 { return { std::make_shared>(x1,x2) }; } - - template - requires (!IsScalarExprOrVar) - inline ScalarExpr - operator/(const X1& x1, const ScalarExpr& x2) - { - return operator/(const_value(x1),x2); - } - - template - requires (!IsScalarExprOrVar) - inline ScalarExpr - operator/(const ScalarExpr& x1, const X2& x2) - { - return operator/(x1, const_value(x2)); - } inline VectorExpr operator/(const VectorExpr& x1, const ScalarExpr& x2) @@ -297,14 +137,6 @@ namespace codac2 return { std::make_shared>(x1,x2) }; } - template - requires (!IsScalarExprOrVar) - inline VectorExpr - operator/(const VectorExpr& x1, const X2& x2) - { - return operator/(x1, const_value(x2)); - } - // Other operators inline ScalarExpr @@ -313,22 +145,6 @@ namespace codac2 return { std::make_shared>(x1,x2) }; } - template - requires (!IsScalarExprOrVar) - inline ScalarExpr - pow(const X1& x1, const ScalarExpr& x2) - { - return pow(const_value(x1),x2); - } - - template - requires (!IsScalarExprOrVar) - inline ScalarExpr - pow(const ScalarExpr& x1, const X2& x2) - { - return pow(x1,const_value(x2)); - } - inline ScalarExpr sqr(const ScalarExpr& x1) { @@ -543,12 +359,6 @@ namespace codac2 return { std::make_shared>(x...) }; } - inline ScalarExpr - ind(Index i, const VectorExpr& x1) - { - return { std::make_shared>(x1,i) }; - } - template inline MatrixExpr mat(const std::shared_ptr>&... x) diff --git a/src/core/functions/analytic/codac2_analytic_variables.cpp b/src/core/functions/analytic/codac2_analytic_variables.cpp index 1495e9e9..cdce629c 100644 --- a/src/core/functions/analytic/codac2_analytic_variables.cpp +++ b/src/core/functions/analytic/codac2_analytic_variables.cpp @@ -19,10 +19,6 @@ using namespace codac2; ScalarVar::ScalarVar() { } - ScalarVar::ScalarVar(const ScalarVar& x) - : AnalyticVarExpr(x) - { } - std::shared_ptr ScalarVar::arg_copy() const { return std::make_shared(*this); @@ -40,7 +36,8 @@ using namespace codac2; AnalyticExprWrapper ScalarVar::operator-() const { - return { std::make_shared>(*this) }; + return { std::make_shared>( + std::dynamic_pointer_cast>(this->copy())) }; } @@ -52,10 +49,6 @@ using namespace codac2; assert_release(n > 0); } - VectorVar::VectorVar(const VectorVar& x) - : AnalyticVarExpr(x), _n(x._n) - { } - std::shared_ptr VectorVar::arg_copy() const { return std::make_shared(*this); diff --git a/src/core/functions/analytic/codac2_analytic_variables.h b/src/core/functions/analytic/codac2_analytic_variables.h index aa4bce1d..8ac4441f 100644 --- a/src/core/functions/analytic/codac2_analytic_variables.h +++ b/src/core/functions/analytic/codac2_analytic_variables.h @@ -41,17 +41,6 @@ namespace codac2 void replace_expr([[maybe_unused]] const ExprID& old_expr_id, [[maybe_unused]] const std::shared_ptr& new_expr) { } - - // to remove - operator std::shared_ptr>() const - { - return std::dynamic_pointer_cast>(this->copy()); - } - - operator AnalyticExprWrapper() const - { - return { std::dynamic_pointer_cast>(this->copy()) }; - } virtual bool belongs_to_args_list(const FunctionArgsList& args) const { @@ -67,7 +56,6 @@ namespace codac2 public: ScalarVar(); - ScalarVar(const ScalarVar& x); std::shared_ptr arg_copy() const; std::shared_ptr copy() const; @@ -81,7 +69,6 @@ namespace codac2 public: explicit VectorVar(Index n); - VectorVar(const VectorVar& x); std::shared_ptr arg_copy() const; std::shared_ptr copy() const; diff --git a/src/core/functions/codac2_ExprBase.h b/src/core/functions/codac2_ExprBase.h index 8ae3045d..47394eaa 100644 --- a/src/core/functions/codac2_ExprBase.h +++ b/src/core/functions/codac2_ExprBase.h @@ -25,7 +25,6 @@ namespace codac2 public: ExprID(); - ExprID(const ExprID& i) = default; Index id() const; bool operator==(const ExprID& i) const; bool operator<(const ExprID& i) const; diff --git a/src/core/trajectory/codac2_TrajectoryBase.h b/src/core/trajectory/codac2_TrajectoryBase.h index a7f766cc..84d7b98f 100644 --- a/src/core/trajectory/codac2_TrajectoryBase.h +++ b/src/core/trajectory/codac2_TrajectoryBase.h @@ -84,6 +84,7 @@ namespace codac2 return p; } + // Implementation in codac2_Trajectory_operator.h AnalyticFunction::Domain> as_function() const; }; } \ No newline at end of file diff --git a/src/core/trajectory/codac2_Trajectory_operator.h b/src/core/trajectory/codac2_Trajectory_operator.h index 58ce6fe1..1806f2e5 100644 --- a/src/core/trajectory/codac2_Trajectory_operator.h +++ b/src/core/trajectory/codac2_Trajectory_operator.h @@ -11,6 +11,7 @@ #include "codac2_analytic_operations.h" #include "codac2_SampledTrajectory.h" +#include "codac2_AnalyticExprWrapper.h" namespace codac2 { @@ -52,7 +53,7 @@ namespace codac2 using O = typename ArgWrapper::Domain; - AnalyticOperationExpr(const TrajectoryBase& x1, const std::shared_ptr>& x2) + AnalyticOperationExpr(const TrajectoryBase& x1, const ScalarExpr& x2) : OperationExprBase>(x2), _x1(x1) { } diff --git a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp index 8fabf900..47abb017 100644 --- a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp +++ b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp @@ -75,12 +75,11 @@ TEST_CASE("AnalyticFunction") } { - // todo: remove call to "const_value" method - CHECK(AnalyticFunction({}, const_value(+Interval(4,5))).eval(m) == Interval(4,5)); - CHECK(AnalyticFunction({}, const_value(+4)).eval(m) == 4); - CHECK(AnalyticFunction({}, const_value(+4.)).eval(m) == 4.); - CHECK(AnalyticFunction({}, const_value(Vector({2,9}))).eval(m) == Vector({2,9})); - CHECK(AnalyticFunction({}, const_value(IntervalVector(3))).eval(m) == IntervalVector({{-oo,oo},{-oo,oo},{-oo,oo}})); + CHECK(AnalyticFunction({}, +Interval(4,5)).eval(m) == Interval(4,5)); + CHECK(AnalyticFunction({}, +4).eval(m) == 4); + CHECK(AnalyticFunction({}, +4.).eval(m) == 4.); + CHECK(AnalyticFunction({}, Vector({2,9})).eval(m) == Vector({2,9})); + CHECK(AnalyticFunction({}, IntervalVector(3)).eval(m) == IntervalVector({{-oo,oo},{-oo,oo},{-oo,oo}})); ScalarVar x1; ScalarVar x2; @@ -261,6 +260,59 @@ TEST_CASE("AnalyticFunction") CHECK(f.eval(Interval(-1,1)) == Interval(0)); } + { + // Scalar outputs + { + AnalyticFunction f1({}, (int)3); + CHECK(f1.eval() == Interval(3)); + + AnalyticFunction f2({}, (double)3.); + CHECK(f2.eval() == Interval(3)); + + AnalyticFunction f3({}, Interval(3.)); + CHECK(f3.eval() == Interval(3)); + + ScalarVar x; + AnalyticFunction f4({x}, x*x); + CHECK(f4.eval(2.) == Interval(4)); + } + + // Vectorial outputs + { + AnalyticFunction f1({}, { (int)3 }); + CHECK(f1.eval() == IntervalVector({3})); + + AnalyticFunction f2({}, { (double)3. }); + CHECK(f2.eval() == IntervalVector({3})); + + AnalyticFunction f3({}, { Interval(3.) }); + CHECK(f3.eval() == IntervalVector({3})); + + ScalarVar x; + AnalyticFunction f4({x}, { x*x }); + CHECK(f4.eval(2.) == IntervalVector({4})); + + AnalyticFunction f_2args({x}, { x*x,x*x }); + CHECK(f_2args.eval(1.) == IntervalVector::constant(2,{1})); + AnalyticFunction f_3args({x}, { x,x*x,1 }); + CHECK(f_3args.eval(1.) == IntervalVector::constant(3,{1})); + AnalyticFunction f_4args({x}, { x,x*x,1,x }); + CHECK(f_4args.eval(1.) == IntervalVector::constant(4,{1})); + AnalyticFunction f_5args({x}, { x,x*x,1,x,x }); + CHECK(f_5args.eval(1.) == IntervalVector::constant(5,{1})); + AnalyticFunction f_6args({x}, { x,x*x,1,x,x,1*x }); + CHECK(f_6args.eval(1.) == IntervalVector::constant(6,{1})); + AnalyticFunction f_7args({x}, { x,x*x,1,x,x,1*x,x*x }); + CHECK(f_7args.eval(1.) == IntervalVector::constant(7,{1})); + AnalyticFunction f_8args({x}, { x,x*x,1,x,x,1*x,x*x,1 }); + CHECK(f_8args.eval(1.) == IntervalVector::constant(8,{1})); + AnalyticFunction f_9args({x}, { x,x*x,1,x,x,1*x,x*x,1,x }); + CHECK(f_9args.eval(1.) == IntervalVector::constant(9,{1})); + AnalyticFunction f_10args({x}, { x,x*x,1,x,x,1*x,x*x,1,x,1*x }); + CHECK(f_10args.eval(1.) == IntervalVector::constant(10,{1})); + } + } + // Subvector on variables { VectorVar p(2); diff --git a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py index 92e42974..ce53c67e 100644 --- a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py +++ b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.py @@ -236,6 +236,48 @@ def test_eval(f,*args): self.assertTrue(f.eval(EvalMode.CENTERED,Interval(-1,1)) == Interval(0)) self.assertTrue(f.eval(Interval(-1,1)) == Interval(0)) + # Scalar outputs + f1 = AnalyticFunction([], 3) + self.assertTrue(f1.eval() == Interval(3)) + f2 = AnalyticFunction([], 3.) + self.assertTrue(f2.eval() == Interval(3)) + f3 = AnalyticFunction([], Interval(3.)) + self.assertTrue(f3.eval() == Interval(3)) + x = ScalarVar() + f4 = AnalyticFunction([x], x*x) + self.assertTrue(f4.eval(2.) == Interval(4)) + + # Vectorial outputs + + f1 = AnalyticFunction([], [ 3 ]) + self.assertTrue(f1.eval() == IntervalVector([3])) + f2 = AnalyticFunction([], [ 3. ]) + self.assertTrue(f2.eval() == IntervalVector([3])) + f3 = AnalyticFunction([], [ Interval(3.) ]) + self.assertTrue(f3.eval() == IntervalVector([3])) + x = ScalarVar() + f4 = AnalyticFunction([x], [ x*x ]) + self.assertTrue(f4.eval(2.) == IntervalVector([4])) + + f_2args = AnalyticFunction([x], [ x*x,x*x ]) + self.assertTrue(f_2args.eval(1.) == IntervalVector.constant(2,[1])) + f_3args = AnalyticFunction([x], [ x,x*x,1 ]) + self.assertTrue(f_3args.eval(1.) == IntervalVector.constant(3,[1])) + f_4args = AnalyticFunction([x], [ x,x*x,1,x ]) + self.assertTrue(f_4args.eval(1.) == IntervalVector.constant(4,[1])) + f_5args = AnalyticFunction([x], [ x,x*x,1,x,x ]) + self.assertTrue(f_5args.eval(1.) == IntervalVector.constant(5,[1])) + f_6args = AnalyticFunction([x], [ x,x*x,1,x,x,1*x ]) + self.assertTrue(f_6args.eval(1.) == IntervalVector.constant(6,[1])) + f_7args = AnalyticFunction([x], [ x,x*x,1,x,x,1*x,x*x ]) + self.assertTrue(f_7args.eval(1.) == IntervalVector.constant(7,[1])) + f_8args = AnalyticFunction([x], [ x,x*x,1,x,x,1*x,x*x,1 ]) + self.assertTrue(f_8args.eval(1.) == IntervalVector.constant(8,[1])) + f_9args = AnalyticFunction([x], [ x,x*x,1,x,x,1*x,x*x,1,x ]) + self.assertTrue(f_9args.eval(1.) == IntervalVector.constant(9,[1])) + f_10args = AnalyticFunction([x], [ x,x*x,1,x,x,1*x,x*x,1,x,1*x ]) + self.assertTrue(f_10args.eval(1.) == IntervalVector.constant(10,[1])) + # Subvector on variables p = VectorVar(2) x = VectorVar(4) diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp index 7fdbb147..ab2695cb 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp @@ -88,11 +88,22 @@ TEST_CASE("SampledTrajectory as operator (nd case)") auto sampled_traj = analytic_traj.sampled(1e-2); auto g = sampled_traj.as_function(); - AnalyticFunction h { - {t}, - vec(1.*ind(0,g(t)),1.*ind(1,g(t))) - }; + { + AnalyticFunction h { + {t}, + g(t) + }; + + for(double t = 0 ; t < 5 ; t+=1e-2) + CHECK(Approx(h.real_eval(t)) == Vector({2*cos(t),sin(2*t)})); + } + { + AnalyticFunction h { + {t}, + { g(t)[0],g(t)[1] } + }; - for(double t = 0 ; t < 5 ; t+=1e-2) - CHECK(Approx(h.real_eval(t)) == Vector({2*cos(t),sin(2*t)})); + for(double t = 0 ; t < 5 ; t+=1e-2) + CHECK(Approx(h.real_eval(t)) == Vector({2*cos(t),sin(2*t)})); + } } \ No newline at end of file From 656aea97803eced78c240c1806867687d4c31efa Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Thu, 26 Dec 2024 15:54:35 +0100 Subject: [PATCH 09/18] [fnc] renaming types --- python/src/core/codac2_py_core.cpp | 18 +-- .../core/contractors/codac2_py_CtcInverse.h | 21 +-- .../contractors/codac2_py_CtcInverseNotIn.h | 17 +-- .../analytic/codac2_py_AnalyticExprWrapper.h | 2 +- .../analytic/codac2_py_AnalyticFunction.h | 12 +- .../analytic/codac2_py_analytic_variables.cpp | 10 +- python/src/core/paver/codac2_py_pave.cpp | 4 +- .../core/separators/codac2_py_SepInverse.h | 15 ++- .../separators/codac2_py_SepTransform.cpp | 4 +- .../codac2_py_AnalyticTrajectory.cpp | 4 +- .../trajectory/codac2_py_TrajectoryBase.h | 2 +- .../graphics/figures/codac2_py_Figure2D.cpp | 16 +-- src/core/CMakeLists.txt | 3 +- src/core/contractors/codac2_CtcInverse.h | 12 +- src/core/contractors/codac2_CtcInverseNotIn.h | 4 +- src/core/contractors/codac2_directed_ctc.cpp | 82 ++++++------ src/core/contractors/codac2_directed_ctc.h | 90 ++++++------- src/core/domains/codac2_Wrapper.h | 1 - .../functions/analytic/codac2_AnalyticExpr.h | 34 ++--- .../analytic/codac2_AnalyticExprWrapper.h | 27 ++-- .../analytic/codac2_AnalyticFunction.h | 36 +++--- .../functions/analytic/codac2_AnalyticType.h | 54 ++++++++ .../analytic/codac2_ScalarExprList.h | 26 ++-- .../functions/analytic/codac2_ValueType.h | 64 +++++++++ .../analytic/codac2_analytic_constants.h | 6 +- .../analytic/codac2_analytic_operations.h | 122 +++++++++--------- .../analytic/codac2_analytic_values.h | 98 -------------- .../analytic/codac2_analytic_variables.cpp | 18 +-- .../analytic/codac2_analytic_variables.h | 10 +- src/core/functions/set/codac2_SetExpr.h | 4 +- .../functions/set/codac2_set_operations.h | 4 +- src/core/functions/set/codac2_set_operators.h | 4 +- src/core/separators/codac2_SepInverse.h | 4 +- src/core/separators/codac2_SepTransform.h | 4 +- .../trajectory/codac2_SampledTrajectory.h | 2 +- src/core/trajectory/codac2_TrajectoryBase.h | 7 +- .../trajectory/codac2_Trajectory_operator.h | 36 +++--- src/graphics/figures/codac2_Figure2D.cpp | 2 +- src/graphics/figures/codac2_Figure2D.h | 4 +- 39 files changed, 457 insertions(+), 426 deletions(-) create mode 100644 src/core/functions/analytic/codac2_AnalyticType.h create mode 100644 src/core/functions/analytic/codac2_ValueType.h delete mode 100644 src/core/functions/analytic/codac2_analytic_values.h diff --git a/python/src/core/codac2_py_core.cpp b/python/src/core/codac2_py_core.cpp index 0ec5f4fd..977560bb 100644 --- a/python/src/core/codac2_py_core.cpp +++ b/python/src/core/codac2_py_core.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include "codac2_py_AnalyticFunction.h" @@ -139,10 +139,10 @@ PYBIND11_MODULE(_core, m) export_CtcIdentity(m, py_ctc_iv); export_CtcInnerOuter(m, py_ctc_iv); export_CtcInter(m, py_ctc_iv); - export_CtcInverse(m,"CtcInverse_Interval",py_ctc_iv); - export_CtcInverse(m,"CtcInverse_IntervalVector",py_ctc_iv); - export_CtcInverseNotIn(m,"CtcInverseNotIn_Interval",py_ctc_iv); - export_CtcInverseNotIn(m,"CtcInverseNotIn_IntervalVector",py_ctc_iv); + export_CtcInverse(m,"CtcInverse_Interval",py_ctc_iv); + export_CtcInverse(m,"CtcInverse_IntervalVector",py_ctc_iv); + export_CtcInverseNotIn(m,"CtcInverseNotIn_Interval",py_ctc_iv); + export_CtcInverseNotIn(m,"CtcInverseNotIn_IntervalVector",py_ctc_iv); export_CtcLazy(m, py_ctc_iv); export_CtcNot(m, py_ctc_iv); export_CtcPolar(m, py_ctc_iv); @@ -193,8 +193,8 @@ PYBIND11_MODULE(_core, m) export_ScalarExpr(m); export_VectorExpr(m); - export_AnalyticFunction(m,"AnalyticFunction_Scalar"); - export_AnalyticFunction(m,"AnalyticFunction_Vector"); + export_AnalyticFunction(m,"AnalyticFunction_Scalar"); + export_AnalyticFunction(m,"AnalyticFunction_Vector"); export_ScalarVar(m); export_VectorVar(m); export_expression_operations(m); @@ -214,8 +214,8 @@ PYBIND11_MODULE(_core, m) export_SepCtcBoundary(m,py_sep); export_SepCtcPair(m,py_sep); export_SepInter(m,py_sep); - export_SepInverse(m,"SepInverse_Interval",py_sep); - export_SepInverse(m,"SepInverse_IntervalVector",py_sep); + export_SepInverse(m,"SepInverse_Interval",py_sep); + export_SepInverse(m,"SepInverse_IntervalVector",py_sep); export_SepNot(m,py_sep); export_SepPolygon(m,py_sep); export_SepProj(m,py_sep); diff --git a/python/src/core/contractors/codac2_py_CtcInverse.h b/python/src/core/contractors/codac2_py_CtcInverse.h index c88ab18d..02b6942e 100644 --- a/python/src/core/contractors/codac2_py_CtcInverse.h +++ b/python/src/core/contractors/codac2_py_CtcInverse.h @@ -19,31 +19,32 @@ using namespace codac2; namespace py = pybind11; using namespace pybind11::literals; -template +template void export_CtcInverse(py::module& m, const std::string& export_name, py::class_,pyCtcIntervalVector>& pyctc) { - py::class_> exported(m, export_name.c_str(), pyctc, CTCINVERSE_MAIN); + using D = typename T::Domain; + py::class_> exported(m, export_name.c_str(), pyctc, CTCINVERSE_MAIN); exported - .def(py::init>&, const T&, bool>(), + .def(py::init&, const D&, bool>(), "f"_a, "y"_a, "with_centered_form"_a = true, - CTCINVERSE_Y_CTCINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_ARGWRAPPER_Y_DOMAIN_REF_CONST_Y_REF_BOOL_BOOL); + CTCINVERSE_Y_CTCINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CONST_Y_REF_BOOL_BOOL); - if constexpr(std::is_same_v) // separators only associated with interval vectors + if constexpr(std::is_same_v) // separators only associated with interval vectors { exported - .def(py::init>&, const pyCtcIntervalVector&, bool>(), + .def(py::init&, const pyCtcIntervalVector&, bool>(), "f"_a, "c"_a, "with_centered_form"_a = true, - CTCINVERSE_Y_CTCINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_ARGWRAPPER_Y_DOMAIN_REF_CONST_C_REF_BOOL_BOOL); + CTCINVERSE_Y_CTCINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CONST_C_REF_BOOL_BOOL); } exported - .def(CONTRACT_BOX_METHOD(CtcInverse_, + .def(CONTRACT_BOX_METHOD(CtcInverse_, VOID_CTCINVERSE_Y_CONTRACT_X_REF_VARIADIC_CONST)) - .def("function", &CtcInverse_::function, - CONST_ANALYTICFUNCTION_TYPENAME_ARGWRAPPER_Y_DOMAIN_REF_CTCINVERSE_Y_FUNCTION_CONST) + .def("function", &CtcInverse_::function, + CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CTCINVERSE_Y_FUNCTION_CONST) ; } \ No newline at end of file diff --git a/python/src/core/contractors/codac2_py_CtcInverseNotIn.h b/python/src/core/contractors/codac2_py_CtcInverseNotIn.h index 3c483173..8b5e761c 100644 --- a/python/src/core/contractors/codac2_py_CtcInverseNotIn.h +++ b/python/src/core/contractors/codac2_py_CtcInverseNotIn.h @@ -19,27 +19,28 @@ using namespace codac2; namespace py = pybind11; using namespace pybind11::literals; -template +template void export_CtcInverseNotIn(py::module& m, const std::string& export_name, py::class_,pyCtcIntervalVector>& pyctc) { - py::class_> exported(m, export_name.c_str(), pyctc, CTCINVERSE_MAIN); + using D = typename T::Domain; + py::class_> exported(m, export_name.c_str(), pyctc, CTCINVERSE_MAIN); exported - .def(py::init>&, const T&, bool>(), + .def(py::init&, const D&, bool>(), "f"_a, "y"_a, "with_centered_form"_a = true, - CTCINVERSENOTIN_YX_CTCINVERSENOTIN_CONST_ANALYTICFUNCTION_TYPENAME_ARGWRAPPER_Y_DOMAIN_REF_CONST_Y_REF_BOOL); + CTCINVERSENOTIN_YX_CTCINVERSENOTIN_CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CONST_Y_REF_BOOL); - if constexpr(std::is_same_v) // separators only associated with interval vectors + if constexpr(std::is_same_v) // separators only associated with interval vectors { exported - .def(py::init>&, const pyCtcIntervalVector&, bool>(), + .def(py::init&, const pyCtcIntervalVector&, bool>(), "f"_a, "c"_a, "with_centered_form"_a = true, - CTCINVERSENOTIN_YX_CTCINVERSENOTIN_CONST_ANALYTICFUNCTION_TYPENAME_ARGWRAPPER_Y_DOMAIN_REF_CONST_C_REF_BOOL); + CTCINVERSENOTIN_YX_CTCINVERSENOTIN_CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CONST_C_REF_BOOL); } exported - .def(CONTRACT_BOX_METHOD(CtcInverseNotIn, + .def(CONTRACT_BOX_METHOD(CtcInverseNotIn, VOID_CTCINVERSENOTIN_YX_CONTRACT_X_REF_CONST)) ; diff --git a/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h b/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h index c51485c8..291bb618 100644 --- a/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticExprWrapper.h @@ -80,7 +80,7 @@ inline void export_VectorExpr(py::module& m) matlab::test_integer(index); return x[matlab::input_index(index)]; }, py::return_value_policy::reference_internal, - ANALYTICEXPRWRAPPER_SCALAROPVALUE_ANALYTICEXPRWRAPPER_T_OPERATORCOMPO_INDEX_CONST) + ANALYTICEXPRWRAPPER_SCALARTYPE_ANALYTICEXPRWRAPPER_T_OPERATORCOMPO_INDEX_CONST) .def("__pos__", [](const VectorExpr& e1) { return e1; }, py::is_operator()) .def(py::self + py::self) diff --git a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h index ae636ad7..8df9ce3f 100644 --- a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h @@ -90,7 +90,7 @@ using namespace pybind11::literals; ; \ -AnalyticExprWrapper pyobj_to_ScalarExpr(const py::object& obj) +AnalyticExprWrapper pyobj_to_ScalarExpr(const py::object& obj) { if(py::isinstance(obj)) return obj.cast(); @@ -102,11 +102,11 @@ std::shared_ptr pyobj_to_ExprBase(const py::object& obj) { if(obj) { - if(py::isinstance>(obj)) - return obj.cast>()->copy(); + if(py::isinstance>(obj)) + return obj.cast>()->copy(); - else if(py::isinstance>(obj)) - return obj.cast>()->copy(); + else if(py::isinstance>(obj)) + return obj.cast>()->copy(); } assert_release("invalid expression"); @@ -153,7 +153,7 @@ void export_AnalyticFunction(py::module& m, const std::string& export_name) ), ANALYTICFUNCTION_T_ANALYTICFUNCTION_CONST_FUNCTIONARGSLIST_REF_CONST_ANALYTICEXPRWRAPPER_T_REF) ; - if constexpr(std::is_same_v) + if constexpr(std::is_same_v) { exported.def(py::init( [](const std::vector& l, const std::vector& v_expr) diff --git a/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp b/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp index 08f15fa4..d397409f 100644 --- a/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp +++ b/python/src/core/functions/analytic/codac2_py_analytic_variables.cpp @@ -68,7 +68,7 @@ ScalarExpr get_item(const VectorVar& v, Index_type i) if(i < 0 || i >= static_cast(v.size())) throw py::index_error("index is out of range"); - return ScalarExpr(std::dynamic_pointer_cast>(v[static_cast(i)]->copy())); + return ScalarExpr(std::dynamic_pointer_cast>(v[static_cast(i)]->copy())); } void export_VectorVar(py::module& m) @@ -94,22 +94,22 @@ void export_VectorVar(py::module& m) exported.def("__call__", [](const VectorVar& v, Index_type i) -> ScalarExpr { return get_item(v, i); - }, ANALYTICEXPRWRAPPER_SCALAROPVALUE_VECTORVAR_OPERATORCOMPO_INDEX_CONST); + }, ANALYTICEXPRWRAPPER_SCALARTYPE_VECTORVAR_OPERATORCOMPO_INDEX_CONST); else exported.def("__getitem__", [](const VectorVar& v, Index_type i) -> ScalarExpr { return get_item(v, i); - }, ANALYTICEXPRWRAPPER_SCALAROPVALUE_VECTORVAR_OPERATORCOMPO_INDEX_CONST); + }, ANALYTICEXPRWRAPPER_SCALARTYPE_VECTORVAR_OPERATORCOMPO_INDEX_CONST); exported .def("subvector", [](const VectorVar& v, Index_type i, Index_type j) -> VectorExpr { matlab::test_integer(i, j); - return VectorExpr(std::dynamic_pointer_cast>( + return VectorExpr(std::dynamic_pointer_cast>( v.subvector(matlab::input_index(i),matlab::input_index(j))->copy())); - }, ANALYTICEXPRWRAPPER_VECTOROPVALUE_VECTORVAR_SUBVECTOR_INDEX_INDEX_CONST) + }, ANALYTICEXPRWRAPPER_VECTORTYPE_VECTORVAR_SUBVECTOR_INDEX_INDEX_CONST) .def("__pos__", [](const VectorVar& e1) { return VectorExpr(VectorExpr(e1)); }, py::is_operator()) .def("__add__", [](const VectorVar& e1, const VectorVar& e2) { return VectorExpr(VectorExpr(e1) + VectorExpr(e2)); }, py::is_operator()) diff --git a/python/src/core/paver/codac2_py_pave.cpp b/python/src/core/paver/codac2_py_pave.cpp index 2554b65d..685f1b9b 100644 --- a/python/src/core/paver/codac2_py_pave.cpp +++ b/python/src/core/paver/codac2_py_pave.cpp @@ -28,11 +28,11 @@ void export_pave(py::module& m) PAVINGINOUT_PAVE_CONST_INTERVALVECTOR_REF_CONST_SEPBASE_REF_DOUBLE, "x"_a, "s"_a, "eps"_a); - m.def("sivia_", (PavingInOut (*)(const IntervalVector&,const AnalyticFunction&,const Interval&,double))&codac2::sivia, + m.def("sivia_", (PavingInOut (*)(const IntervalVector&,const AnalyticFunction&,const Interval&,double))&codac2::sivia, PAVINGINOUT_SIVIA_CONST_INTERVALVECTOR_REF_CONST_ANALYTICFUNCTION_Y_REF_CONST_TYPENAME_Y_DOMAIN_REF_DOUBLE, "x"_a, "f"_a, "y"_a, "eps"_a); - m.def("sivia_", (PavingInOut (*)(const IntervalVector&,const AnalyticFunction&,const IntervalVector&,double))&codac2::sivia, + m.def("sivia_", (PavingInOut (*)(const IntervalVector&,const AnalyticFunction&,const IntervalVector&,double))&codac2::sivia, PAVINGINOUT_SIVIA_CONST_INTERVALVECTOR_REF_CONST_ANALYTICFUNCTION_Y_REF_CONST_TYPENAME_Y_DOMAIN_REF_DOUBLE, "x"_a, "f"_a, "y"_a, "eps"_a); } \ No newline at end of file diff --git a/python/src/core/separators/codac2_py_SepInverse.h b/python/src/core/separators/codac2_py_SepInverse.h index bf8bcdc0..d6fcca5e 100644 --- a/python/src/core/separators/codac2_py_SepInverse.h +++ b/python/src/core/separators/codac2_py_SepInverse.h @@ -21,27 +21,28 @@ using namespace codac2; namespace py = pybind11; using namespace pybind11::literals; -template +template void export_SepInverse(py::module& m, const std::string& export_name, py::class_& pysep) { - py::class_> exported(m, export_name.c_str(), pysep, SEPINVERSE_MAIN); + using D = typename T::Domain; + py::class_> exported(m, export_name.c_str(), pysep, SEPINVERSE_MAIN); exported - .def(py::init>&,const T&,bool>(), - SEPINVERSE_Y_SEPINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_ARGWRAPPER_Y_DOMAIN_REF_CONST_Y_REF_BOOL, + .def(py::init&,const D&,bool>(), + SEPINVERSE_Y_SEPINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CONST_Y_REF_BOOL, "f"_a, "y"_a, "with_centered_form"_a = true); if constexpr(std::is_same_v) // separators only associated with interval vectors { exported - .def(py::init>&,const pySep&,bool>(), - SEPINVERSE_Y_SEPINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_ARGWRAPPER_Y_DOMAIN_REF_CONST_S_REF_BOOL, + .def(py::init&,const pySep&,bool>(), + SEPINVERSE_Y_SEPINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CONST_S_REF_BOOL, "f"_a, "s"_a, "with_centered_form"_a = true); } exported - .def("separate", &SepInverse::separate, + .def("separate", &SepInverse::separate, BOXPAIR_SEPCTCPAIR_SEPARATE_CONST_INTERVALVECTOR_REF_CONST, "x"_a) ; diff --git a/python/src/core/separators/codac2_py_SepTransform.cpp b/python/src/core/separators/codac2_py_SepTransform.cpp index cf97daf8..19e8751a 100644 --- a/python/src/core/separators/codac2_py_SepTransform.cpp +++ b/python/src/core/separators/codac2_py_SepTransform.cpp @@ -22,7 +22,7 @@ using namespace pybind11::literals; void export_SepTransform(py::module& m, py::class_& pysep) { - using FNC = AnalyticFunction; + using FNC = AnalyticFunction; py::class_ exported(m, "SepTransform", pysep, SEPTRANSFORM_MAIN); exported @@ -36,7 +36,7 @@ void export_SepTransform(py::module& m, py::class_& pysep) return std::make_unique(s.copy(), _f.cast(), _f_inv.cast()); }), - SEPTRANSFORM_SEPTRANSFORM_CONST_S_REF_CONST_ANALYTICFUNCTION_VECTOROPVALUE_REF_CONST_ANALYTICFUNCTION_VECTOROPVALUE_REF, + SEPTRANSFORM_SEPTRANSFORM_CONST_S_REF_CONST_ANALYTICFUNCTION_VECTORTYPE_REF_CONST_ANALYTICFUNCTION_VECTORTYPE_REF, "s"_a, "f"_a, "f_inv"_a) .def("separate", &SepTransform::separate, diff --git a/python/src/core/trajectory/codac2_py_AnalyticTrajectory.cpp b/python/src/core/trajectory/codac2_py_AnalyticTrajectory.cpp index f742c3f4..c3a49279 100644 --- a/python/src/core/trajectory/codac2_py_AnalyticTrajectory.cpp +++ b/python/src/core/trajectory/codac2_py_AnalyticTrajectory.cpp @@ -40,6 +40,6 @@ void _export_AnalyticTrajectory(py::module& m, const string& class_name) void export_AnalyticTrajectory(py::module& m) { - _export_AnalyticTrajectory(m, "AnalyticTrajectory_Scalar"); - _export_AnalyticTrajectory(m, "AnalyticTrajectory_Vector"); + _export_AnalyticTrajectory(m, "AnalyticTrajectory_Scalar"); + _export_AnalyticTrajectory(m, "AnalyticTrajectory_Vector"); } \ No newline at end of file diff --git a/python/src/core/trajectory/codac2_py_TrajectoryBase.h b/python/src/core/trajectory/codac2_py_TrajectoryBase.h index 34bf43b9..9c91c5e9 100644 --- a/python/src/core/trajectory/codac2_py_TrajectoryBase.h +++ b/python/src/core/trajectory/codac2_py_TrajectoryBase.h @@ -84,7 +84,7 @@ void export_TrajectoryBase(py::class_& pyclass) VIRTUAL_SAMPLEDTRAJECTORY_T_TRAJECTORYBASE_T_SAMPLED_DOUBLE_CONST, "dt"_a) - .def("primitive", [](const S& x, const typename S::ScalarType& y0, double dt) + .def("primitive", [](const S& x, const typename S::Type::Scalar& y0, double dt) { return x.primitive(y0,dt); }, diff --git a/python/src/graphics/figures/codac2_py_Figure2D.cpp b/python/src/graphics/figures/codac2_py_Figure2D.cpp index e4898aea..56b38b27 100644 --- a/python/src/graphics/figures/codac2_py_Figure2D.cpp +++ b/python/src/graphics/figures/codac2_py_Figure2D.cpp @@ -132,9 +132,9 @@ void export_Figure2D(py::module& m) if(x_traj) { - if(py::isinstance>(x_traj)) + if(py::isinstance>(x_traj)) { - fig.draw_trajectory(x_traj.cast>(),s); + fig.draw_trajectory(x_traj.cast>(),s); return; } @@ -146,9 +146,9 @@ void export_Figure2D(py::module& m) } assert_release(false && - "provided trajectory is not of type AnalyticTrajectory or SampledTrajectory"); + "provided trajectory is not of type AnalyticTrajectory or SampledTrajectory"); }, - VOID_FIGURE2D_DRAW_TRAJECTORY_CONST_ANALYTICTRAJECTORY_VECTOROPVALUE_REF_CONST_STYLEPROPERTIES_REF, + VOID_FIGURE2D_DRAW_TRAJECTORY_CONST_ANALYTICTRAJECTORY_VECTORTYPE_REF_CONST_STYLEPROPERTIES_REF, "x"_a, "s"_a=StyleProperties()) // Robots @@ -228,9 +228,9 @@ void export_Figure2D(py::module& m) if(x_traj) { - if(py::isinstance>(x_traj)) + if(py::isinstance>(x_traj)) { - DefaultView::draw_trajectory(x_traj.cast>(),s); + DefaultView::draw_trajectory(x_traj.cast>(),s); return; } @@ -242,9 +242,9 @@ void export_Figure2D(py::module& m) } assert_release(false && - "provided trajectory is not of type AnalyticTrajectory or SampledTrajectory"); + "provided trajectory is not of type AnalyticTrajectory or SampledTrajectory"); }, - VOID_FIGURE2D_DRAW_TRAJECTORY_CONST_ANALYTICTRAJECTORY_VECTOROPVALUE_REF_CONST_STYLEPROPERTIES_REF, + VOID_FIGURE2D_DRAW_TRAJECTORY_CONST_ANALYTICTRAJECTORY_VECTORTYPE_REF_CONST_STYLEPROPERTIES_REF, "x"_a, "s"_a=StyleProperties()) // Robots diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index feb6f021..96a2e9ee 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -69,13 +69,14 @@ ${CMAKE_CURRENT_SOURCE_DIR}/functions/codac2_VarBase.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_constants.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_operations.h - ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_values.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_variables.cpp ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_analytic_variables.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticExpr.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticExprWrapper.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticFunction.h + ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_AnalyticType.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_ScalarExprList.h + ${CMAKE_CURRENT_SOURCE_DIR}/functions/analytic/codac2_ValueType.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/set/codac2_set_operations.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/set/codac2_set_operators.h ${CMAKE_CURRENT_SOURCE_DIR}/functions/set/codac2_set_variables.h diff --git a/src/core/contractors/codac2_CtcInverse.h b/src/core/contractors/codac2_CtcInverse.h index d0756159..b1b0cc05 100644 --- a/src/core/contractors/codac2_CtcInverse.h +++ b/src/core/contractors/codac2_CtcInverse.h @@ -27,14 +27,14 @@ namespace codac2 template requires IsCtcBaseOrPtr - CtcInverse(const AnalyticFunction::Domain>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false) + CtcInverse(const AnalyticFunction::Type>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false) : _f(f), _ctc_y(ctc_y), _with_centered_form(with_centered_form), _is_not_in(is_not_in) { assert_release([&]() { return f.output_size() == size_of(ctc_y); }() && "CtcInverse: invalid dimension of image argument ('y' or 'ctc_y')"); } - CtcInverse(const AnalyticFunction::Domain>& f, const Y& y, bool with_centered_form = true, bool is_not_in = false) + CtcInverse(const AnalyticFunction::Type>& f, const Y& y, bool with_centered_form = true, bool is_not_in = false) : CtcInverse(f, CtcWrapper_(y), with_centered_form, is_not_in) { } @@ -122,14 +122,14 @@ namespace codac2 _f.intersect_from_args(v, x...); // updating input values } - const AnalyticFunction::Domain>& function() const + const AnalyticFunction::Type>& function() const { return _f; } protected: - const AnalyticFunction::Domain> _f; + const AnalyticFunction::Type> _f; const Collection> _ctc_y; bool _with_centered_form; bool _is_not_in = false; @@ -140,7 +140,7 @@ namespace codac2 { public: - CtcInverse_(const AnalyticFunction::Domain>& f, const Y& y, bool with_centered_form = true, bool is_not_in = false) + CtcInverse_(const AnalyticFunction::Type>& f, const Y& y, bool with_centered_form = true, bool is_not_in = false) : Ctc,X>(f.args()[0]->size() /* f must have only one arg, see following assert */), CtcInverse(f, y, with_centered_form,is_not_in) { @@ -149,7 +149,7 @@ namespace codac2 template requires IsCtcBaseOrPtr - CtcInverse_(const AnalyticFunction::Domain>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false) + CtcInverse_(const AnalyticFunction::Type>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false) : Ctc,X>(f.args()[0]->size() /* f must have only one arg, see following assert */), CtcInverse(f, ctc_y, with_centered_form,is_not_in) { diff --git a/src/core/contractors/codac2_CtcInverseNotIn.h b/src/core/contractors/codac2_CtcInverseNotIn.h index da0cada7..eb166de2 100644 --- a/src/core/contractors/codac2_CtcInverseNotIn.h +++ b/src/core/contractors/codac2_CtcInverseNotIn.h @@ -21,7 +21,7 @@ namespace codac2 { public: - CtcInverseNotIn(const AnalyticFunction::Domain>& f, const Y& y, bool with_centered_form = true) + CtcInverseNotIn(const AnalyticFunction::Type>& f, const Y& y, bool with_centered_form = true) : CtcUnion(f.args()[0]->size() /* f must have only one arg, see following assert */) { assert_release(f.args().size() == 1 && "f must have only one arg"); @@ -46,7 +46,7 @@ namespace codac2 template requires IsCtcBaseOrPtr - CtcInverseNotIn(const AnalyticFunction::Domain>& f, const C& ctc_compl, bool with_centered_form = true) + CtcInverseNotIn(const AnalyticFunction::Type>& f, const C& ctc_compl, bool with_centered_form = true) : CtcUnion(f.args()[0]->size() /* f must have only one arg, see following assert */) { assert_release(f.args().size() == 1 && "f must have only one arg"); diff --git a/src/core/contractors/codac2_directed_ctc.cpp b/src/core/contractors/codac2_directed_ctc.cpp index db25b48a..fddb1f55 100644 --- a/src/core/contractors/codac2_directed_ctc.cpp +++ b/src/core/contractors/codac2_directed_ctc.cpp @@ -22,7 +22,7 @@ using namespace codac2; return x1; } - ScalarOpValue AddOp::fwd(const ScalarOpValue& x1) + ScalarType AddOp::fwd(const ScalarType& x1) { return { fwd(x1.m), @@ -40,7 +40,7 @@ using namespace codac2; return x1; } - VectorOpValue AddOp::fwd(const VectorOpValue& x1) + VectorType AddOp::fwd(const VectorType& x1) { return { fwd(x1.m), @@ -60,7 +60,7 @@ using namespace codac2; return x1; } - MatrixOpValue AddOp::fwd(const MatrixOpValue& x1) + MatrixType AddOp::fwd(const MatrixType& x1) { return { fwd(x1.m), @@ -83,7 +83,7 @@ using namespace codac2; return x1 + x2; } - ScalarOpValue AddOp::fwd(const ScalarOpValue& x1, const ScalarOpValue& x2) + ScalarType AddOp::fwd(const ScalarType& x1, const ScalarType& x2) { assert(x1.da.size() == x2.da.size()); return { @@ -105,7 +105,7 @@ using namespace codac2; return x1 + x2; } - VectorOpValue AddOp::fwd(const VectorOpValue& x1, const VectorOpValue& x2) + VectorType AddOp::fwd(const VectorType& x1, const VectorType& x2) { assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols()); return { @@ -129,7 +129,7 @@ using namespace codac2; return x1 + x2; } - MatrixOpValue AddOp::fwd(const MatrixOpValue& x1, const MatrixOpValue& x2) + MatrixType AddOp::fwd(const MatrixType& x1, const MatrixType& x2) { return { fwd(x1.m, x2.m), @@ -154,7 +154,7 @@ using namespace codac2; return -x1; } - ScalarOpValue SubOp::fwd(const ScalarOpValue& x1) + ScalarType SubOp::fwd(const ScalarType& x1) { return { fwd(x1.m), @@ -175,7 +175,7 @@ using namespace codac2; return -x1; } - VectorOpValue SubOp::fwd(const VectorOpValue& x1) + VectorType SubOp::fwd(const VectorType& x1) { return { fwd(x1.m), @@ -197,7 +197,7 @@ using namespace codac2; return -x1; } - MatrixOpValue SubOp::fwd(const MatrixOpValue& x1) + MatrixType SubOp::fwd(const MatrixType& x1) { return { fwd(x1.m), @@ -222,7 +222,7 @@ using namespace codac2; return x1 - x2; } - ScalarOpValue SubOp::fwd(const ScalarOpValue& x1, const ScalarOpValue& x2) + ScalarType SubOp::fwd(const ScalarType& x1, const ScalarType& x2) { assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols()); return { @@ -244,7 +244,7 @@ using namespace codac2; return x1 - x2; } - VectorOpValue SubOp::fwd(const VectorOpValue& x1, const VectorOpValue& x2) + VectorType SubOp::fwd(const VectorType& x1, const VectorType& x2) { assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols()); return { @@ -268,7 +268,7 @@ using namespace codac2; return x1 - x2; } - MatrixOpValue SubOp::fwd(const MatrixOpValue& x1, const MatrixOpValue& x2) + MatrixType SubOp::fwd(const MatrixType& x1, const MatrixType& x2) { assert(x1.a.cols() == x2.a.cols() && x1.a.rows() == x2.a.rows()); return { @@ -294,7 +294,7 @@ using namespace codac2; return x1 * x2; } - ScalarOpValue MulOp::fwd(const ScalarOpValue& x1, const ScalarOpValue& x2) + ScalarType MulOp::fwd(const ScalarType& x1, const ScalarType& x2) { assert(x1.da.rows() == 1); assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols()); @@ -321,7 +321,7 @@ using namespace codac2; return x1 * x2; } - VectorOpValue MulOp::fwd(const ScalarOpValue& x1, const VectorOpValue& x2) + VectorType MulOp::fwd(const ScalarType& x1, const VectorType& x2) { assert(x1.da.rows() == 1); assert(x1.da.cols() == x2.da.cols()); @@ -352,7 +352,7 @@ using namespace codac2; return MulOp::fwd(x2,x1); } - VectorOpValue MulOp::fwd(const VectorOpValue& x1, const ScalarOpValue& x2) + VectorType MulOp::fwd(const VectorType& x1, const ScalarType& x2) { return MulOp::fwd(x2,x1); } @@ -371,9 +371,9 @@ using namespace codac2; return s; } - //ScalarOpValue MulOp::fwd(const RowOpValue& x1, const VectorOpValue& x2) + //ScalarType MulOp::fwd(const RowType& x1, const VectorType& x2) //{ - // // RowOpValue not yet defined + // // RowType not yet defined //} void MulOp::bwd(const Interval& y, IntervalRow& x1, IntervalVector& x2) @@ -410,7 +410,7 @@ using namespace codac2; return x1 * x2; } - VectorOpValue MulOp::fwd(const MatrixOpValue& x1, const VectorOpValue& x2) + VectorType MulOp::fwd(const MatrixType& x1, const VectorType& x2) { return { fwd(x1.a, /* <<----- x1.m */ x2.m), @@ -507,7 +507,7 @@ using namespace codac2; return x1 / x2; } - ScalarOpValue DivOp::fwd(const ScalarOpValue& x1, const ScalarOpValue& x2) + ScalarType DivOp::fwd(const ScalarType& x1, const ScalarType& x2) { assert(x1.da.size() == x2.da.size()); @@ -533,7 +533,7 @@ using namespace codac2; return x1 / x2; } - VectorOpValue DivOp::fwd(const VectorOpValue& x1, const ScalarOpValue& x2) + VectorType DivOp::fwd(const VectorType& x1, const ScalarType& x2) { assert(x1.da.size() == x2.da.size()); @@ -563,7 +563,7 @@ using namespace codac2; return pow(x1,x2); } - ScalarOpValue PowOp::fwd(const ScalarOpValue& x1, const ScalarOpValue& x2) + ScalarType PowOp::fwd(const ScalarType& x1, const ScalarType& x2) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -590,7 +590,7 @@ using namespace codac2; return sqr(x1); } - ScalarOpValue SqrOp::fwd(const ScalarOpValue& x1) + ScalarType SqrOp::fwd(const ScalarType& x1) { assert(x1.da.rows() == 1); @@ -619,7 +619,7 @@ using namespace codac2; return sqrt(x1); } - ScalarOpValue SqrtOp::fwd(const ScalarOpValue& x1) + ScalarType SqrtOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -648,7 +648,7 @@ using namespace codac2; return exp(x1); } - ScalarOpValue ExpOp::fwd(const ScalarOpValue& x1) + ScalarType ExpOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -675,7 +675,7 @@ using namespace codac2; return log(x1); } - ScalarOpValue LogOp::fwd(const ScalarOpValue& x1) + ScalarType LogOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -704,7 +704,7 @@ using namespace codac2; return cos(x1); } - ScalarOpValue CosOp::fwd(const ScalarOpValue& x1) + ScalarType CosOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -731,7 +731,7 @@ using namespace codac2; return sin(x1); } - ScalarOpValue SinOp::fwd(const ScalarOpValue& x1) + ScalarType SinOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -758,7 +758,7 @@ using namespace codac2; return tan(x1); } - ScalarOpValue TanOp::fwd(const ScalarOpValue& x1) + ScalarType TanOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -785,7 +785,7 @@ using namespace codac2; return acos(x1); } - ScalarOpValue AcosOp::fwd(const ScalarOpValue& x1) + ScalarType AcosOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -814,7 +814,7 @@ using namespace codac2; return asin(x1); } - ScalarOpValue AsinOp::fwd(const ScalarOpValue& x1) + ScalarType AsinOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -843,7 +843,7 @@ using namespace codac2; return atan(x1); } - ScalarOpValue AtanOp::fwd(const ScalarOpValue& x1) + ScalarType AtanOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -870,7 +870,7 @@ using namespace codac2; return atan2(x1,x2); } - ScalarOpValue Atan2Op::fwd(const ScalarOpValue& x1, const ScalarOpValue& x2) + ScalarType Atan2Op::fwd(const ScalarType& x1, const ScalarType& x2) { assert(x1.da.rows() == 1); assert(x1.da.rows() == x2.da.rows() && x1.da.cols() == x2.da.cols()); @@ -901,7 +901,7 @@ using namespace codac2; return cosh(x1); } - ScalarOpValue CoshOp::fwd(const ScalarOpValue& x1) + ScalarType CoshOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -928,7 +928,7 @@ using namespace codac2; return sinh(x1); } - ScalarOpValue SinhOp::fwd(const ScalarOpValue& x1) + ScalarType SinhOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -955,7 +955,7 @@ using namespace codac2; return tanh(x1); } - ScalarOpValue TanhOp::fwd(const ScalarOpValue& x1) + ScalarType TanhOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -982,7 +982,7 @@ using namespace codac2; return abs(x1); } - ScalarOpValue AbsOp::fwd(const ScalarOpValue& x1) + ScalarType AbsOp::fwd(const ScalarType& x1) { IntervalMatrix d(1,x1.da.size()); for(Index i = 0 ; i < d.size() ; i++) @@ -1010,7 +1010,7 @@ using namespace codac2; return x1[i]; } - ScalarOpValue ComponentOp::fwd(const VectorOpValue& x1, Index i) + ScalarType ComponentOp::fwd(const VectorType& x1, Index i) { assert(i >= 0 && i < x1.a.rows()); return { @@ -1036,7 +1036,7 @@ using namespace codac2; return x1.subvector(i,j); } - VectorOpValue SubvectorOp::fwd(const VectorOpValue& x1, Index i, Index j) + VectorType SubvectorOp::fwd(const VectorType& x1, Index i, Index j) { assert(i >= 0 && i < x1.a.rows() && j >= i && j < x1.a.rows()); return { @@ -1085,7 +1085,7 @@ using namespace codac2; return Interval::empty(); // unhandled case } - ScalarOpValue DetOp::fwd(const MatrixOpValue& x) + ScalarType DetOp::fwd(const MatrixType& x) { return { fwd(x.m), @@ -1127,7 +1127,7 @@ using namespace codac2; return DetOp::fwd(m); } - ScalarOpValue DetOp::fwd(const VectorOpValue& x1, const VectorOpValue& x2) + ScalarType DetOp::fwd(const VectorType& x1, const VectorType& x2) { IntervalMatrix m(2,2); m.col(0) = x1.m; m.col(1) = x2.m; @@ -1162,7 +1162,7 @@ using namespace codac2; return DetOp::fwd(m); } - ScalarOpValue DetOp::fwd(const VectorOpValue& x1, const VectorOpValue& x2, const VectorOpValue& x3) + ScalarType DetOp::fwd(const VectorType& x1, const VectorType& x2, const VectorType& x3) { IntervalMatrix m(3,3); m.col(0) = x1.m; m.col(1) = x2.m; m.col(2) = x3.m; diff --git a/src/core/contractors/codac2_directed_ctc.h b/src/core/contractors/codac2_directed_ctc.h index 4b9ad460..3c3f6124 100644 --- a/src/core/contractors/codac2_directed_ctc.h +++ b/src/core/contractors/codac2_directed_ctc.h @@ -10,7 +10,7 @@ #pragma once #include -#include "codac2_analytic_values.h" +#include "codac2_AnalyticType.h" #include "codac2_template_tools.h" #include "codac2_IntervalRow.h" @@ -20,28 +20,28 @@ namespace codac2 { // Unary operations static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); static IntervalVector fwd(const IntervalVector& x1); - static VectorOpValue fwd(const VectorOpValue& x1); + static VectorType fwd(const VectorType& x1); static void bwd(const IntervalVector& y, IntervalVector& x1); static IntervalMatrix fwd(const IntervalMatrix& x1); - static MatrixOpValue fwd(const MatrixOpValue& x1); + static MatrixType fwd(const MatrixType& x1); static void bwd(const IntervalMatrix& y, IntervalMatrix& x1); // Binary operations static Interval fwd(const Interval& x1, const Interval& x2); - static ScalarOpValue fwd(const ScalarOpValue& x1, const ScalarOpValue& x2); + static ScalarType fwd(const ScalarType& x1, const ScalarType& x2); static void bwd(const Interval& y, Interval& x1, Interval& x2); static IntervalVector fwd(const IntervalVector& x1, const IntervalVector& x2); - static VectorOpValue fwd(const VectorOpValue& x1, const VectorOpValue& x2); + static VectorType fwd(const VectorType& x1, const VectorType& x2); static void bwd(const IntervalVector& y, IntervalVector& x1, IntervalVector& x2); static IntervalMatrix fwd(const IntervalMatrix& x1, const IntervalMatrix& x2); - static MatrixOpValue fwd(const MatrixOpValue& x1, const MatrixOpValue& x2); + static MatrixType fwd(const MatrixType& x1, const MatrixType& x2); static void bwd(const IntervalMatrix& y, IntervalMatrix& x1, IntervalMatrix& x2); }; @@ -49,188 +49,188 @@ namespace codac2 { // Unary operations static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); static IntervalVector fwd(const IntervalVector& x1); - static VectorOpValue fwd(const VectorOpValue& x1); + static VectorType fwd(const VectorType& x1); static void bwd(const IntervalVector& y, IntervalVector& x1); static IntervalMatrix fwd(const IntervalMatrix& x1); - static MatrixOpValue fwd(const MatrixOpValue& x1); + static MatrixType fwd(const MatrixType& x1); static void bwd(const IntervalMatrix& y, IntervalMatrix& x1); // Binary operations static Interval fwd(const Interval& x1, const Interval& x2); - static ScalarOpValue fwd(const ScalarOpValue& x1, const ScalarOpValue& x2); + static ScalarType fwd(const ScalarType& x1, const ScalarType& x2); static void bwd(const Interval& y, Interval& x1, Interval& x2); static IntervalVector fwd(const IntervalVector& x1, const IntervalVector& x2); - static VectorOpValue fwd(const VectorOpValue& x1, const VectorOpValue& x2); + static VectorType fwd(const VectorType& x1, const VectorType& x2); static void bwd(const IntervalVector& y, IntervalVector& x1, IntervalVector& x2); static IntervalMatrix fwd(const IntervalMatrix& x1, const IntervalMatrix& x2); - static MatrixOpValue fwd(const MatrixOpValue& x1, const MatrixOpValue& x2); + static MatrixType fwd(const MatrixType& x1, const MatrixType& x2); static void bwd(const IntervalMatrix& y, IntervalMatrix& x1, IntervalMatrix& x2); }; struct MulOp { static Interval fwd(const Interval& x1, const Interval& x2); - static ScalarOpValue fwd(const ScalarOpValue& x1, const ScalarOpValue& x2); + static ScalarType fwd(const ScalarType& x1, const ScalarType& x2); static void bwd(const Interval& y, Interval& x1, Interval& x2); static IntervalVector fwd(const Interval& x1, const IntervalVector& x2); - static VectorOpValue fwd(const ScalarOpValue& x1, const VectorOpValue& x2); + static VectorType fwd(const ScalarType& x1, const VectorType& x2); static void bwd(const IntervalVector& y, Interval& x1, IntervalVector& x2); static IntervalVector fwd(const IntervalVector& x1, const Interval& x2); - static VectorOpValue fwd(const VectorOpValue& x1, const ScalarOpValue& x2); + static VectorType fwd(const VectorType& x1, const ScalarType& x2); static void bwd(const IntervalVector& y, IntervalVector& x1, Interval& x2); static Interval fwd(const IntervalRow& x1, const IntervalVector& x2); - //static ScalarOpValue fwd(const RowOpValue& x1, const VectorOpValue& x2); // RowOpValue not yet defined + //static ScalarType fwd(const RowType& x1, const VectorType& x2); // RowType not yet defined static void bwd(const Interval& y, IntervalRow& x1, IntervalVector& x2); static IntervalVector fwd(const IntervalMatrix& x1, const IntervalVector& x2); - static VectorOpValue fwd(const MatrixOpValue& x1, const VectorOpValue& x2); + static VectorType fwd(const MatrixType& x1, const VectorType& x2); static void bwd(const IntervalVector& y, IntervalMatrix& x1, IntervalVector& x2); }; struct DivOp { static Interval fwd(const Interval& x1, const Interval& x2); - static ScalarOpValue fwd(const ScalarOpValue& x1, const ScalarOpValue& x2); + static ScalarType fwd(const ScalarType& x1, const ScalarType& x2); static void bwd(const Interval& y, Interval& x1, Interval& x2); static IntervalVector fwd(const IntervalVector& x1, const Interval& x2); - static VectorOpValue fwd(const VectorOpValue& x1, const ScalarOpValue& x2); + static VectorType fwd(const VectorType& x1, const ScalarType& x2); static void bwd(const IntervalVector& y, IntervalVector& x1, Interval& x2); }; struct PowOp { static Interval fwd(const Interval& x1, const Interval& x2); - static ScalarOpValue fwd(const ScalarOpValue& x1, const ScalarOpValue& x2); + static ScalarType fwd(const ScalarType& x1, const ScalarType& x2); static void bwd(const Interval& y, Interval& x1, Interval& x2); }; struct SqrOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct SqrtOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct ExpOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct LogOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct CosOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct SinOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct TanOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct AcosOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct AsinOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct AtanOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct Atan2Op { static Interval fwd(const Interval& x1, const Interval& x2); - static ScalarOpValue fwd(const ScalarOpValue& x1, const ScalarOpValue& x2); + static ScalarType fwd(const ScalarType& x1, const ScalarType& x2); static void bwd(const Interval& y, Interval& x1, Interval& x2); }; struct CoshOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct SinhOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct TanhOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct AbsOp { static Interval fwd(const Interval& x1); - static ScalarOpValue fwd(const ScalarOpValue& x1); + static ScalarType fwd(const ScalarType& x1); static void bwd(const Interval& y, Interval& x1); }; struct ComponentOp { static Interval fwd(const IntervalVector& x1, Index i); - static ScalarOpValue fwd(const VectorOpValue& x1, Index i); + static ScalarType fwd(const VectorType& x1, Index i); static void bwd(const Interval& y, IntervalVector& x1, Index i); }; struct SubvectorOp { static IntervalVector fwd(const IntervalVector& x1, Index i, Index j); - static VectorOpValue fwd(const VectorOpValue& x1, Index i, Index j); + static VectorType fwd(const VectorType& x1, Index i, Index j); static void bwd(const IntervalVector& y, IntervalVector& x1, Index i, Index j); }; @@ -244,8 +244,8 @@ namespace codac2 } template - requires (std::is_base_of_v && ...) - static VectorOpValue fwd(const X&... x) + requires (std::is_base_of_v && ...) + static VectorType fwd(const X&... x) { IntervalMatrix d(sizeof...(X),std::get<0>(std::tie(x...)).da.cols()); Index i = 0; @@ -287,8 +287,8 @@ namespace codac2 } template - requires (std::is_base_of_v && ...) - static MatrixOpValue fwd(const X&... x) + requires (std::is_base_of_v && ...) + static MatrixType fwd(const X&... x) { throw std::runtime_error("MatrixOp not fully implemented yet"); return { @@ -313,17 +313,17 @@ namespace codac2 { // For matrices static Interval fwd(const IntervalMatrix& x); - static ScalarOpValue fwd(const MatrixOpValue& x); + static ScalarType fwd(const MatrixType& x); static void bwd(const Interval& y, IntervalMatrix& x); // For two vectors (merged into a 2×2 matrix) static Interval fwd(const IntervalVector& x1, const IntervalVector& x2); - static ScalarOpValue fwd(const VectorOpValue& x1, const VectorOpValue& x2); + static ScalarType fwd(const VectorType& x1, const VectorType& x2); static void bwd(const Interval& y, IntervalVector& x1, IntervalVector& x2); // For three vectors (merged into a 3×3 matrix) static Interval fwd(const IntervalVector& x1, const IntervalVector& x2, const IntervalVector& x3); - static ScalarOpValue fwd(const VectorOpValue& x1, const VectorOpValue& x2, const VectorOpValue& x3); + static ScalarType fwd(const VectorType& x1, const VectorType& x2, const VectorType& x3); static void bwd(const Interval& y, IntervalVector& x1, IntervalVector& x2, IntervalVector& x3); }; } \ No newline at end of file diff --git a/src/core/domains/codac2_Wrapper.h b/src/core/domains/codac2_Wrapper.h index baa9779e..b58544db 100644 --- a/src/core/domains/codac2_Wrapper.h +++ b/src/core/domains/codac2_Wrapper.h @@ -14,7 +14,6 @@ #include "codac2_Matrix.h" #include "codac2_IntervalVector.h" #include "codac2_IntervalMatrix.h" -#include "codac2_analytic_values.h" namespace codac2 { diff --git a/src/core/functions/analytic/codac2_AnalyticExpr.h b/src/core/functions/analytic/codac2_AnalyticExpr.h index a0bd43af..671c285d 100644 --- a/src/core/functions/analytic/codac2_AnalyticExpr.h +++ b/src/core/functions/analytic/codac2_AnalyticExpr.h @@ -19,7 +19,7 @@ namespace codac2 { - using ValuesMap = std::map>; + using ValuesMap = std::map>; template class AnalyticExpr : public ExprBase @@ -112,33 +112,33 @@ namespace codac2 }; template<> - class AnalyticOperationExpr : public AnalyticExpr, public OperationExprBase> + class AnalyticOperationExpr : public AnalyticExpr, public OperationExprBase> { public: - AnalyticOperationExpr(const std::shared_ptr>& x1, Index i) - : OperationExprBase>(x1), _i(i) + AnalyticOperationExpr(const std::shared_ptr>& x1, Index i) + : OperationExprBase>(x1), _i(i) { } std::shared_ptr copy() const { - return std::make_shared>(*this); + return std::make_shared>(*this); } void replace_expr(const ExprID& old_expr_id, const std::shared_ptr& new_expr) { - return OperationExprBase>::replace_expr(old_expr_id, new_expr); + return OperationExprBase>::replace_expr(old_expr_id, new_expr); } - ScalarOpValue fwd_eval(ValuesMap& v, Index total_input_size) const + ScalarType fwd_eval(ValuesMap& v, Index total_input_size) const { - return AnalyticExpr::init_value( + return AnalyticExpr::init_value( v, ComponentOp::fwd(std::get<0>(this->_x)->fwd_eval(v, total_input_size), _i)); } void bwd_eval(ValuesMap& v) const { - ComponentOp::bwd(AnalyticExpr::value(v).a, std::get<0>(this->_x)->value(v).a, _i); + ComponentOp::bwd(AnalyticExpr::value(v).a, std::get<0>(this->_x)->value(v).a, _i); std::get<0>(this->_x)->bwd_eval(v); } @@ -153,33 +153,33 @@ namespace codac2 }; template<> - class AnalyticOperationExpr : public AnalyticExpr, public OperationExprBase> + class AnalyticOperationExpr : public AnalyticExpr, public OperationExprBase> { public: - AnalyticOperationExpr(const std::shared_ptr>& x1, Index i, Index j) - : OperationExprBase>(x1), _i(i), _j(j) + AnalyticOperationExpr(const std::shared_ptr>& x1, Index i, Index j) + : OperationExprBase>(x1), _i(i), _j(j) { } std::shared_ptr copy() const { - return std::make_shared>(*this); + return std::make_shared>(*this); } void replace_expr(const ExprID& old_expr_id, const std::shared_ptr& new_expr) { - return OperationExprBase>::replace_expr(old_expr_id, new_expr); + return OperationExprBase>::replace_expr(old_expr_id, new_expr); } - VectorOpValue fwd_eval(ValuesMap& v, Index total_input_size) const + VectorType fwd_eval(ValuesMap& v, Index total_input_size) const { - return AnalyticExpr::init_value( + return AnalyticExpr::init_value( v, SubvectorOp::fwd(std::get<0>(this->_x)->fwd_eval(v, total_input_size), _i, _j)); } void bwd_eval(ValuesMap& v) const { - SubvectorOp::bwd(AnalyticExpr::value(v).a, std::get<0>(this->_x)->value(v).a, _i, _j); + SubvectorOp::bwd(AnalyticExpr::value(v).a, std::get<0>(this->_x)->value(v).a, _i, _j); std::get<0>(this->_x)->bwd_eval(v); } diff --git a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h index 972c6be2..d2756e83 100644 --- a/src/core/functions/analytic/codac2_AnalyticExprWrapper.h +++ b/src/core/functions/analytic/codac2_AnalyticExprWrapper.h @@ -10,10 +10,17 @@ #pragma once #include "codac2_AnalyticExpr.h" -#include "codac2_analytic_constants.h" +#include "codac2_ValueType.h" +#include "codac2_analytic_variables.h" namespace codac2 { + template + struct AnalyticExprWrapper; + + template + AnalyticExprWrapper::Type> const_value(const T& x); + template struct AnalyticExprWrapper : public std::shared_ptr> { @@ -22,31 +29,31 @@ namespace codac2 { } AnalyticExprWrapper(const ScalarVar& e) - requires std::is_same_v + requires std::is_same_v : std::shared_ptr>({ std::dynamic_pointer_cast>(e.copy()) }) { } AnalyticExprWrapper(const VectorVar& e) - requires std::is_same_v + requires std::is_same_v : std::shared_ptr>({ std::dynamic_pointer_cast>(e.copy()) }) { } template AnalyticExprWrapper(const V& e) - requires std::is_same_v::Domain,T> + requires std::is_same_v::Type,T> : std::shared_ptr>(const_value(e)) { } - inline AnalyticExprWrapper operator[](Index i) const - requires std::is_same_v + inline AnalyticExprWrapper operator[](Index i) const + requires std::is_same_v { - return { std::make_shared>(*this,i) }; + return { std::make_shared>(*this,i) }; } }; - using ScalarExpr = AnalyticExprWrapper; - using VectorExpr = AnalyticExprWrapper; - using MatrixExpr = AnalyticExprWrapper; + using ScalarExpr = AnalyticExprWrapper; + using VectorExpr = AnalyticExprWrapper; + using MatrixExpr = AnalyticExprWrapper; template concept IsScalarExprOrVar = (std::is_base_of_v || std::is_base_of_v); diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index dc796d6d..ded5cc69 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -35,13 +35,13 @@ namespace codac2 { return static_cast(static_cast(a) | static_cast(b)); } template - requires std::is_base_of_v + requires std::is_base_of_v class AnalyticFunction : public FunctionBase> { public: AnalyticFunction(const FunctionArgsList& args, const ScalarExprList& y) - requires(std::is_same_v) + requires(std::is_same_v) : FunctionBase>(args, y) { assert_release(y->belongs_to_args_list(this->args()) && @@ -89,7 +89,7 @@ namespace codac2 auto flatten_x = cart_prod(x...); assert(x_.da.rows() == x_.a.size() && x_.da.cols() == flatten_x.size()); - if constexpr(std::is_same_v) + if constexpr(std::is_same_v) return x_.m + (x_.da*(flatten_x-flatten_x.mid()))[0]; else return x_.m + (x_.da*(flatten_x-flatten_x.mid())).col(0); @@ -104,7 +104,7 @@ namespace codac2 else { auto flatten_x = cart_prod(x...); - if constexpr(std::is_same_v) + if constexpr(std::is_same_v) return x_.a & (x_.m + (x_.da*(flatten_x-flatten_x.mid()))[0]); else { @@ -131,10 +131,10 @@ namespace codac2 Index output_size() const { - if constexpr(std::is_same_v) + if constexpr(std::is_same_v) return 1; - else if constexpr(std::is_same_v) + else if constexpr(std::is_same_v) { // A dump evaluation is performed to estimate the dimension // of the image of this function. A natural evaluation is assumed @@ -151,9 +151,9 @@ namespace codac2 friend std::ostream& operator<<(std::ostream& os, [[maybe_unused]] const AnalyticFunction& f) { - if constexpr(std::is_same_v) + if constexpr(std::is_same_v) os << "scalar function"; - else if constexpr(std::is_same_v) + else if constexpr(std::is_same_v) os << "vector function"; return os; } @@ -178,7 +178,7 @@ namespace codac2 for(Index k = p ; k < p+size_of(x) ; k++) d(k-p,k) = 1.; - using D_DOMAIN = typename ArgWrapper::Domain; + using D_DOMAIN = typename ValueType::Type; v[this->args()[i]->unique_id()] = std::make_shared(typename D_DOMAIN::Domain(x).mid(), x, d, true); @@ -195,7 +195,7 @@ namespace codac2 void intersect_value_from_arg_map(const ValuesMap& v, D& x, Index i) const { assert(v.find(this->args()[i]->unique_id()) != v.end() && "argument cannot be found"); - x &= std::dynamic_pointer_cast::Domain>(v.at(this->args()[i]->unique_id()))->a; + x &= std::dynamic_pointer_cast::Type>(v.at(this->args()[i]->unique_id()))->a; } template @@ -232,28 +232,28 @@ namespace codac2 }; AnalyticFunction(const FunctionArgsList&, double) -> - AnalyticFunction; + AnalyticFunction; AnalyticFunction(const FunctionArgsList&, const Interval&) -> - AnalyticFunction; + AnalyticFunction; AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> - AnalyticFunction; + AnalyticFunction; AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> - AnalyticFunction; + AnalyticFunction; AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> - AnalyticFunction; + AnalyticFunction; AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> - AnalyticFunction; + AnalyticFunction; AnalyticFunction(const FunctionArgsList&, std::initializer_list) -> - AnalyticFunction; + AnalyticFunction; template AnalyticFunction(const FunctionArgsList&, const T&) -> - AnalyticFunction::Domain>; + AnalyticFunction::Type>; } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_AnalyticType.h b/src/core/functions/analytic/codac2_AnalyticType.h new file mode 100644 index 00000000..c5c7eda8 --- /dev/null +++ b/src/core/functions/analytic/codac2_AnalyticType.h @@ -0,0 +1,54 @@ +/** + * \file codac2_AnalyticType.h + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#pragma once + +#include "codac2_Interval.h" +#include "codac2_Vector.h" +#include "codac2_Matrix.h" +#include "codac2_IntervalVector.h" +#include "codac2_IntervalMatrix.h" + +namespace codac2 +{ + struct AnalyticTypeBase + { + virtual ~AnalyticTypeBase() = default; + }; + + template + struct AnalyticType : public AnalyticTypeBase + { + using Scalar = S; + using Domain = T; + + T m; + T a; + M da; + bool def_domain; + + AnalyticType() = delete; + + AnalyticType(const T& m_, const T& a_, const M& da_, bool def_domain_) + : m(m_), a(a_), da(da_), def_domain(def_domain_) + { } + + AnalyticType& operator&=(const AnalyticType& x) + { + a &= x.a; + // restore this? da &= x.da; + def_domain &= x.def_domain; + return *this; + } + }; + + using ScalarType = AnalyticType; + using VectorType = AnalyticType; + using MatrixType = AnalyticType; +} \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_ScalarExprList.h b/src/core/functions/analytic/codac2_ScalarExprList.h index 7ac1f630..0d14d49b 100644 --- a/src/core/functions/analytic/codac2_ScalarExprList.h +++ b/src/core/functions/analytic/codac2_ScalarExprList.h @@ -18,20 +18,20 @@ namespace codac2 template concept IsScalar = std::is_same_v || std::is_same_v || - std::is_same_v::Domain,ScalarOpValue>; + std::is_same_v::Type,ScalarType>; - struct ScalarExprList : public AnalyticExprWrapper + struct ScalarExprList : public AnalyticExprWrapper { template requires IsScalar ScalarExprList(const S1& y1) - : AnalyticExprWrapper(vec(to_ScalarExpr(y1))) + : AnalyticExprWrapper(vec(to_ScalarExpr(y1))) { } template requires IsScalar && IsScalar ScalarExprList(const S1& y1, const S2& y2) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1),to_ScalarExpr(y2) )) { } @@ -39,7 +39,7 @@ namespace codac2 template requires IsScalar && IsScalar && IsScalar ScalarExprList(const S1& y1, const S2& y2, const S3& y3) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3) )) { } @@ -47,7 +47,7 @@ namespace codac2 template requires IsScalar && IsScalar && IsScalar && IsScalar ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4) )) { } @@ -55,7 +55,7 @@ namespace codac2 template requires IsScalar && IsScalar && IsScalar && IsScalar && IsScalar ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5) )) { } @@ -66,7 +66,7 @@ namespace codac2 && IsScalar ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, const S6& y6) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), to_ScalarExpr(y6) )) @@ -78,7 +78,7 @@ namespace codac2 && IsScalar && IsScalar ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, const S6& y6, const S7& y7) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), to_ScalarExpr(y6), to_ScalarExpr(y7) )) @@ -90,7 +90,7 @@ namespace codac2 && IsScalar && IsScalar && IsScalar ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, const S6& y6, const S7& y7, const S8& y8) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), to_ScalarExpr(y6), to_ScalarExpr(y7), to_ScalarExpr(y8) )) @@ -102,7 +102,7 @@ namespace codac2 && IsScalar && IsScalar && IsScalar && IsScalar ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, const S6& y6, const S7& y7, const S8& y8, const S9& y9) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), to_ScalarExpr(y6), to_ScalarExpr(y7), to_ScalarExpr(y8), to_ScalarExpr(y9) )) @@ -114,7 +114,7 @@ namespace codac2 && IsScalar && IsScalar && IsScalar && IsScalar && IsScalar ScalarExprList(const S1& y1, const S2& y2, const S3& y3, const S4& y4, const S5& y5, const S6& y6, const S7& y7, const S8& y8, const S9& y9, const S10& y10) - : AnalyticExprWrapper(vec( + : AnalyticExprWrapper(vec( to_ScalarExpr(y1), to_ScalarExpr(y2), to_ScalarExpr(y3), to_ScalarExpr(y4), to_ScalarExpr(y5), to_ScalarExpr(y6), to_ScalarExpr(y7), to_ScalarExpr(y8), to_ScalarExpr(y9), to_ScalarExpr(y10) )) @@ -126,7 +126,7 @@ namespace codac2 } template - requires std::is_same_v::Domain,ScalarOpValue> + requires std::is_same_v::Type,ScalarType> ScalarExpr to_ScalarExpr(const T& e) { return const_value(e); diff --git a/src/core/functions/analytic/codac2_ValueType.h b/src/core/functions/analytic/codac2_ValueType.h new file mode 100644 index 00000000..06086ce1 --- /dev/null +++ b/src/core/functions/analytic/codac2_ValueType.h @@ -0,0 +1,64 @@ +/** + * \file codac2_ValueType.h + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#pragma once + +#include "codac2_Interval.h" +#include "codac2_Vector.h" +#include "codac2_Matrix.h" +#include "codac2_IntervalVector.h" +#include "codac2_IntervalMatrix.h" +#include "codac2_AnalyticType.h" + +namespace codac2 +{ + template + struct ValueType + { }; + + template<> + struct ValueType { + using Type = ScalarType; + }; + + template<> + struct ValueType { + using Type = ScalarType; + }; + + template<> + struct ValueType { + using Type = ScalarType; + }; + + template<> + struct ValueType { + using Type = ScalarType; + }; + + template<> + struct ValueType { + using Type = VectorType; + }; + + template<> + struct ValueType { + using Type = VectorType; + }; + + template<> + struct ValueType { + using Type = MatrixType; + }; + + template<> + struct ValueType { + using Type = MatrixType; + }; +} \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_constants.h b/src/core/functions/analytic/codac2_analytic_constants.h index 72cd7f1e..a3d75b38 100644 --- a/src/core/functions/analytic/codac2_analytic_constants.h +++ b/src/core/functions/analytic/codac2_analytic_constants.h @@ -10,6 +10,8 @@ #pragma once #include "codac2_Index.h" +#include "codac2_ValueType.h" +#include "codac2_AnalyticExprWrapper.h" namespace codac2 { @@ -59,8 +61,8 @@ namespace codac2 }; template - AnalyticExprWrapper::Domain> const_value(const T& x) + AnalyticExprWrapper::Type> const_value(const T& x) { - return { std::make_shared::Domain>>(x) }; + return { std::make_shared::Type>>(x) }; } } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_operations.h b/src/core/functions/analytic/codac2_analytic_operations.h index 0b277860..9960b278 100644 --- a/src/core/functions/analytic/codac2_analytic_operations.h +++ b/src/core/functions/analytic/codac2_analytic_operations.h @@ -11,7 +11,7 @@ #include #include "codac2_AnalyticExpr.h" -#include "codac2_analytic_variables.h" +#include "codac2_AnalyticType.h" #include "codac2_analytic_constants.h" #include "codac2_AnalyticExprWrapper.h" @@ -22,19 +22,19 @@ namespace codac2 inline ScalarExpr operator+(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline VectorExpr operator+(const VectorExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline MatrixExpr operator+(const MatrixExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } // operator+ @@ -42,19 +42,19 @@ namespace codac2 inline ScalarExpr operator+(ScalarExpr x1, ScalarExpr x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline VectorExpr operator+(VectorExpr x1, VectorExpr x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline MatrixExpr operator+(MatrixExpr x1, MatrixExpr x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } // operator- (unary case) @@ -62,19 +62,19 @@ namespace codac2 inline ScalarExpr operator-(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline VectorExpr operator-(const VectorExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline MatrixExpr operator-(const MatrixExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } // operator- @@ -82,19 +82,19 @@ namespace codac2 inline ScalarExpr operator-(const ScalarExpr& x1, const ScalarExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline VectorExpr operator-(const VectorExpr& x1, const VectorExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline MatrixExpr operator-(const MatrixExpr& x1, const MatrixExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } // operator* @@ -102,25 +102,25 @@ namespace codac2 inline ScalarExpr operator*(const ScalarExpr& x1, const ScalarExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline VectorExpr operator*(const ScalarExpr& x1, const VectorExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline VectorExpr operator*(const VectorExpr& x1, const ScalarExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline VectorExpr operator*(const MatrixExpr& x1, const VectorExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } // operator/ @@ -128,13 +128,13 @@ namespace codac2 inline ScalarExpr operator/(const ScalarExpr& x1, const ScalarExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline VectorExpr operator/(const VectorExpr& x1, const ScalarExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } // Other operators @@ -142,97 +142,97 @@ namespace codac2 inline ScalarExpr pow(const ScalarExpr& x1, const ScalarExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline ScalarExpr sqr(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr sqrt(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr exp(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr log(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr cos(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr sin(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr tan(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr acos(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr asin(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr atan(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr atan2(const ScalarExpr& x1, const ScalarExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline ScalarExpr cosh(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr sinh(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr tanh(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr abs(const ScalarExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } // Structural operators @@ -255,8 +255,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1)) }; } @@ -265,8 +265,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2)) }; } @@ -275,8 +275,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3)) }; } @@ -285,8 +285,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4)) }; } @@ -295,8 +295,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5)) }; } @@ -305,8 +305,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6)) }; } @@ -315,8 +315,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7)) }; } @@ -325,8 +325,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8)) }; } @@ -335,8 +335,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8),_add_to_vec(x9)) }; } @@ -345,8 +345,8 @@ namespace codac2 inline VectorExpr vec(const X1& x1, const X2& x2, const X3& x3, const X4& x4, const X5& x5, const X6& x6, const X7& x7, const X8& x8, const X9& x9, const X10& x10) { - return { std::make_shared>( + return { std::make_shared>( _add_to_vec(x1),_add_to_vec(x2),_add_to_vec(x3),_add_to_vec(x4),_add_to_vec(x5),_add_to_vec(x6),_add_to_vec(x7),_add_to_vec(x8),_add_to_vec(x9),_add_to_vec(x10)) }; } @@ -356,15 +356,15 @@ namespace codac2 inline VectorExpr vec(const AnalyticExprWrapper&... x) { - return { std::make_shared>(x...) }; + return { std::make_shared>(x...) }; } template inline MatrixExpr mat(const std::shared_ptr>&... x) { - return { std::make_shared>( - AnalyticOperationExpr(x...)) }; + return { std::make_shared>( + AnalyticOperationExpr(x...)) }; } // Vectorial operations @@ -372,18 +372,18 @@ namespace codac2 inline ScalarExpr det(const MatrixExpr& x1) { - return { std::make_shared>(x1) }; + return { std::make_shared>(x1) }; } inline ScalarExpr det(const VectorExpr& x1, const VectorExpr& x2) { - return { std::make_shared>(x1,x2) }; + return { std::make_shared>(x1,x2) }; } inline ScalarExpr det(const VectorExpr& x1, const VectorExpr& x2, const VectorExpr& x3) { - return { std::make_shared>(x1,x2,x3) }; + return { std::make_shared>(x1,x2,x3) }; } } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_values.h b/src/core/functions/analytic/codac2_analytic_values.h deleted file mode 100644 index 67088752..00000000 --- a/src/core/functions/analytic/codac2_analytic_values.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * \file codac2_analytic_values.h - * ---------------------------------------------------------------------------- - * \date 2024 - * \author Simon Rohou - * \copyright Copyright 2024 Codac Team - * \license GNU Lesser General Public License (LGPL) - */ - -#pragma once - -#include "codac2_Interval.h" -#include "codac2_Vector.h" -#include "codac2_Matrix.h" -#include "codac2_IntervalVector.h" -#include "codac2_IntervalMatrix.h" - -namespace codac2 -{ - struct OpValueBase - { - virtual ~OpValueBase() = default; - }; - - template - struct OpValue : public OpValueBase - { - using Scalar = S; - using Domain = T; - - T m; - T a; - M da; - bool def_domain; - - OpValue() = delete; - - OpValue(const T& m_, const T& a_, const M& da_, bool def_domain_) - : m(m_), a(a_), da(da_), def_domain(def_domain_) - { } - - OpValue& operator&=(const OpValue& x) - { - a &= x.a; - // restore this? da &= x.da; - def_domain &= x.def_domain; - return *this; - } - }; - - using ScalarOpValue = OpValue; - using VectorOpValue = OpValue; - using MatrixOpValue = OpValue; - - template - struct ArgWrapper - { }; - - template<> - struct ArgWrapper { - using Domain = ScalarOpValue; - }; - - template<> - struct ArgWrapper { - using Domain = ScalarOpValue; - }; - - template<> - struct ArgWrapper { - using Domain = ScalarOpValue; - }; - - template<> - struct ArgWrapper { - using Domain = ScalarOpValue; - }; - - template<> - struct ArgWrapper { - using Domain = VectorOpValue; - }; - - template<> - struct ArgWrapper { - using Domain = VectorOpValue; - }; - - template<> - struct ArgWrapper { - using Domain = MatrixOpValue; - }; - - template<> - struct ArgWrapper { - using Domain = MatrixOpValue; - }; -} \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_variables.cpp b/src/core/functions/analytic/codac2_analytic_variables.cpp index cdce629c..90be2abe 100644 --- a/src/core/functions/analytic/codac2_analytic_variables.cpp +++ b/src/core/functions/analytic/codac2_analytic_variables.cpp @@ -34,10 +34,10 @@ using namespace codac2; return 1; } - AnalyticExprWrapper ScalarVar::operator-() const + AnalyticExprWrapper ScalarVar::operator-() const { - return { std::make_shared>( - std::dynamic_pointer_cast>(this->copy())) }; + return { std::make_shared>( + std::dynamic_pointer_cast>(this->copy())) }; } @@ -64,16 +64,16 @@ using namespace codac2; return _n; } - AnalyticExprWrapper VectorVar::operator[](Index i) const + AnalyticExprWrapper VectorVar::operator[](Index i) const { assert_release(i >= 0 && i < _n); - return { std::make_shared>( - std::dynamic_pointer_cast>(this->copy()), i) }; + return { std::make_shared>( + std::dynamic_pointer_cast>(this->copy()), i) }; } - AnalyticExprWrapper VectorVar::subvector(Index i, Index j) const + AnalyticExprWrapper VectorVar::subvector(Index i, Index j) const { assert_release(i >= 0 && i < _n && j >= i && j < _n); - return { std::make_shared>( - std::dynamic_pointer_cast>(this->copy()), i, j) }; + return { std::make_shared>( + std::dynamic_pointer_cast>(this->copy()), i, j) }; } \ No newline at end of file diff --git a/src/core/functions/analytic/codac2_analytic_variables.h b/src/core/functions/analytic/codac2_analytic_variables.h index 8ac4441f..fa436c73 100644 --- a/src/core/functions/analytic/codac2_analytic_variables.h +++ b/src/core/functions/analytic/codac2_analytic_variables.h @@ -51,7 +51,7 @@ namespace codac2 } }; - class ScalarVar : public AnalyticVarExpr + class ScalarVar : public AnalyticVarExpr { public: @@ -61,10 +61,10 @@ namespace codac2 std::shared_ptr copy() const; Index size() const; - AnalyticExprWrapper operator-() const; + AnalyticExprWrapper operator-() const; }; - class VectorVar : public AnalyticVarExpr + class VectorVar : public AnalyticVarExpr { public: @@ -74,8 +74,8 @@ namespace codac2 std::shared_ptr copy() const; Index size() const; - AnalyticExprWrapper operator[](Index i) const; - AnalyticExprWrapper subvector(Index i, Index j) const; + AnalyticExprWrapper operator[](Index i) const; + AnalyticExprWrapper subvector(Index i, Index j) const; protected: diff --git a/src/core/functions/set/codac2_SetExpr.h b/src/core/functions/set/codac2_SetExpr.h index 3f0e548f..0985fbd2 100644 --- a/src/core/functions/set/codac2_SetExpr.h +++ b/src/core/functions/set/codac2_SetExpr.h @@ -147,7 +147,7 @@ namespace codac2 { public: - SetOperationExpr(const AnalyticFunction& f, std::shared_ptr x) + SetOperationExpr(const AnalyticFunction& f, std::shared_ptr x) : OperationExprBase(x), _f(f) { } @@ -182,7 +182,7 @@ namespace codac2 protected: - const AnalyticFunction _f; + const AnalyticFunction _f; }; template<> diff --git a/src/core/functions/set/codac2_set_operations.h b/src/core/functions/set/codac2_set_operations.h index e8dc14f6..d6bb1f4d 100644 --- a/src/core/functions/set/codac2_set_operations.h +++ b/src/core/functions/set/codac2_set_operations.h @@ -85,13 +85,13 @@ namespace codac2 } inline SetExpr_ptr - inverse(const AnalyticFunction& f, const SetExpr_ptr& x1) + inverse(const AnalyticFunction& f, const SetExpr_ptr& x1) { return std::make_shared>(f,x1); } inline SetExpr_ptr - inverse(const AnalyticFunction& f, const IntervalVector& x1) + inverse(const AnalyticFunction& f, const IntervalVector& x1) { return std::make_shared>(f,const_set(x1)); } diff --git a/src/core/functions/set/codac2_set_operators.h b/src/core/functions/set/codac2_set_operators.h index 8a400b4c..c897b1aa 100644 --- a/src/core/functions/set/codac2_set_operators.h +++ b/src/core/functions/set/codac2_set_operators.h @@ -94,12 +94,12 @@ namespace codac2 struct InverseSetOp { - static std::shared_ptr> create_ctc(const AnalyticFunction& f, const std::shared_ptr>& s1) + static std::shared_ptr> create_ctc(const AnalyticFunction& f, const std::shared_ptr>& s1) { return std::make_shared>(f,s1); } - static std::shared_ptr create_sep(const AnalyticFunction& f, const std::shared_ptr& s1) + static std::shared_ptr create_sep(const AnalyticFunction& f, const std::shared_ptr& s1) { return std::make_shared>(f,s1); } diff --git a/src/core/separators/codac2_SepInverse.h b/src/core/separators/codac2_SepInverse.h index 8cc6cbed..ba8c5f8c 100644 --- a/src/core/separators/codac2_SepInverse.h +++ b/src/core/separators/codac2_SepInverse.h @@ -27,13 +27,13 @@ namespace codac2 public: - SepInverse(const AnalyticFunction::Domain>& f, const Y& y, bool with_centered_form = true) + SepInverse(const AnalyticFunction::Type>& f, const Y& y, bool with_centered_form = true) : SepCtcPair(CtcInverseNotIn(f,y,with_centered_form), CtcInverse_(f,y,with_centered_form)) { } template requires (std::is_same_v && IsSepBaseOrPtr) - SepInverse(const AnalyticFunction::Domain>& f, const S& sep_y, bool with_centered_form = true) + SepInverse(const AnalyticFunction::Type>& f, const S& sep_y, bool with_centered_form = true) : SepCtcPair(CtcInverseNotIn(f,CtcInner(sep_y),with_centered_form), CtcInverse_(f,CtcOuter(sep_y),with_centered_form)) { } }; diff --git a/src/core/separators/codac2_SepTransform.h b/src/core/separators/codac2_SepTransform.h index 17835ace..bb08d53f 100644 --- a/src/core/separators/codac2_SepTransform.h +++ b/src/core/separators/codac2_SepTransform.h @@ -25,7 +25,7 @@ namespace codac2 template requires IsSepBaseOrPtr - SepTransform(const S& s, const AnalyticFunction& f, const AnalyticFunction& f_inv) + SepTransform(const S& s, const AnalyticFunction& f, const AnalyticFunction& f_inv) : Sep(f.args()[0]->size() /* f must have only one arg, see following assert */), _sep(s), _ctc_inv(f, IntervalVector(f_inv.args()[0]->size())), _f(f), _f_inv(f_inv) { @@ -39,6 +39,6 @@ namespace codac2 const Collection _sep; const CtcInverse_ _ctc_inv; - const AnalyticFunction _f, _f_inv; + const AnalyticFunction _f, _f_inv; }; } \ No newline at end of file diff --git a/src/core/trajectory/codac2_SampledTrajectory.h b/src/core/trajectory/codac2_SampledTrajectory.h index 004802ee..5b094105 100644 --- a/src/core/trajectory/codac2_SampledTrajectory.h +++ b/src/core/trajectory/codac2_SampledTrajectory.h @@ -31,7 +31,7 @@ namespace codac2 // size is not the std::map::size() ! virtual Index size() const { - if constexpr(std::is_same_v::Domain,Interval>) // if type is scalar: int,double,etc. + if constexpr(std::is_same_v::Type,ScalarType>) return 1; else diff --git a/src/core/trajectory/codac2_TrajectoryBase.h b/src/core/trajectory/codac2_TrajectoryBase.h index 84d7b98f..e7b8a2d9 100644 --- a/src/core/trajectory/codac2_TrajectoryBase.h +++ b/src/core/trajectory/codac2_TrajectoryBase.h @@ -12,6 +12,7 @@ #include "codac2_Interval.h" #include "codac2_Wrapper.h" #include "codac2_AnalyticFunction.h" +#include "codac2_ValueType.h" namespace codac2 { @@ -23,7 +24,7 @@ namespace codac2 { public: - using ScalarType = T; + using Type = ValueType::Type; TrajectoryBase() { } @@ -38,7 +39,7 @@ namespace codac2 auto nan_value() const { - if constexpr(std::is_same_v::Domain,Interval>) // if type is int,double,etc. + if constexpr(std::is_same_v::Type,ScalarType>) return std::numeric_limits::quiet_NaN(); else @@ -85,6 +86,6 @@ namespace codac2 } // Implementation in codac2_Trajectory_operator.h - AnalyticFunction::Domain> as_function() const; + AnalyticFunction::Type> as_function() const; }; } \ No newline at end of file diff --git a/src/core/trajectory/codac2_Trajectory_operator.h b/src/core/trajectory/codac2_Trajectory_operator.h index 1806f2e5..47d1d428 100644 --- a/src/core/trajectory/codac2_Trajectory_operator.h +++ b/src/core/trajectory/codac2_Trajectory_operator.h @@ -12,19 +12,21 @@ #include "codac2_analytic_operations.h" #include "codac2_SampledTrajectory.h" #include "codac2_AnalyticExprWrapper.h" +#include "codac2_ValueType.h" +#include "codac2_Wrapper.h" namespace codac2 { - template::Domain> - requires (std::is_same_v || std::is_same_v) + template + requires (std::is_same_v::Type,ScalarType> || std::is_same_v::Type,VectorType>) struct TrajectoryOp { - static D fwd(const TrajectoryBase& x1, const Interval& x2) + static typename Wrapper::Domain fwd(const TrajectoryBase& x1, const Interval& x2) { return x1(x2); } - static typename ArgWrapper::Domain fwd(const TrajectoryBase& x1, const ScalarOpValue& x2) + static typename ValueType::Type fwd(const TrajectoryBase& x1, const ScalarType& x2) { IntervalMatrix d(x1.size(),x2.da.cols()); @@ -38,7 +40,7 @@ namespace codac2 static void bwd( [[maybe_unused]] const TrajectoryBase& x1, - [[maybe_unused]] const D& y, + [[maybe_unused]] const typename Wrapper::Domain& y, [[maybe_unused]] Interval& x2) { // todo @@ -46,29 +48,25 @@ namespace codac2 }; template - class AnalyticOperationExpr,typename ArgWrapper::Domain,ScalarOpValue> - : public AnalyticExpr::Domain>, public OperationExprBase> + class AnalyticOperationExpr,typename ValueType::Type,ScalarType> + : public AnalyticExpr::Type>, public OperationExprBase> { public: - using O = typename ArgWrapper::Domain; + using O = typename ValueType::Type; AnalyticOperationExpr(const TrajectoryBase& x1, const ScalarExpr& x2) - : OperationExprBase>(x2), _x1(x1) - { } - - AnalyticOperationExpr(const AnalyticOperationExpr& e) - : OperationExprBase>(e), _x1(e._x1) + : OperationExprBase>(x2), _x1(x1) { } std::shared_ptr copy() const { - return std::make_shared,O,ScalarOpValue>>(*this); + return std::make_shared,O,ScalarType>>(*this); } void replace_expr(const ExprID& old_expr_id, const std::shared_ptr& new_expr) { - return OperationExprBase>::replace_expr(old_expr_id, new_expr); + return OperationExprBase>::replace_expr(old_expr_id, new_expr); } O fwd_eval(ValuesMap& v, Index total_input_size) const @@ -92,17 +90,17 @@ namespace codac2 const TrajectoryBase& _x1; }; - + template - AnalyticFunction::Domain> TrajectoryBase::as_function() const + AnalyticFunction::Type> TrajectoryBase::as_function() const { - using D = typename ArgWrapper::Domain; + using D = typename ValueType::Type; ScalarVar t; return {{t}, AnalyticExprWrapper(std::make_shared< AnalyticOperationExpr - , D, ScalarOpValue>>(*this,t)) + , D, ScalarType>>(*this,t)) }; } } \ No newline at end of file diff --git a/src/graphics/figures/codac2_Figure2D.cpp b/src/graphics/figures/codac2_Figure2D.cpp index 608da895..bb18871d 100644 --- a/src/graphics/figures/codac2_Figure2D.cpp +++ b/src/graphics/figures/codac2_Figure2D.cpp @@ -207,7 +207,7 @@ void Figure2D::draw_trajectory(const SampledTrajectory& x, const StylePr draw_polyline(values,s); } -void Figure2D::draw_trajectory(const AnalyticTrajectory& x, const StyleProperties& s) +void Figure2D::draw_trajectory(const AnalyticTrajectory& x, const StyleProperties& s) { draw_trajectory(x.sampled(x.tdomain().diam()/1e4), s); } diff --git a/src/graphics/figures/codac2_Figure2D.h b/src/graphics/figures/codac2_Figure2D.h index 0f2bf9a7..cd5883a5 100644 --- a/src/graphics/figures/codac2_Figure2D.h +++ b/src/graphics/figures/codac2_Figure2D.h @@ -91,7 +91,7 @@ namespace codac2 void draw_pie(const Vector& c, const Interval& r, const Interval& theta, const StyleProperties& s = StyleProperties()); void draw_ellipse(const Vector& c, const Vector& ab, double theta, const StyleProperties& s = StyleProperties()); void draw_trajectory(const SampledTrajectory& x, const StyleProperties& s = StyleProperties()); - void draw_trajectory(const AnalyticTrajectory& x, const StyleProperties& s = StyleProperties()); + void draw_trajectory(const AnalyticTrajectory& x, const StyleProperties& s = StyleProperties()); // Robots void draw_tank(const Vector& x, float size, const StyleProperties& s = StyleProperties()); void draw_AUV(const Vector& x, float size, const StyleProperties& s = StyleProperties()); @@ -212,7 +212,7 @@ namespace codac2 selected_fig()->draw_trajectory(x,s); } - static void draw_trajectory(const AnalyticTrajectory& x, const StyleProperties& s = StyleProperties()) + static void draw_trajectory(const AnalyticTrajectory& x, const StyleProperties& s = StyleProperties()) { auto_init(); selected_fig()->draw_trajectory(x,s); From a137e9abd4dafa057b3b3d69d7b0090027380034 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Thu, 26 Dec 2024 17:45:55 +0100 Subject: [PATCH 10/18] [traj] binding for as_function() method + tests --- python/codac/core/__init__.py | 48 ++++++++++++----- .../codac2_py_AnalyticTrajectory.cpp | 1 + .../codac2_py_SampledTrajectory.cpp | 12 +++++ .../trajectory/codac2_py_TrajectoryBase.h | 8 ++- src/core/trajectory/codac2_TrajectoryBase.h | 6 +-- .../codac2_tests_SampledTrajectory.py | 53 ++++++++++++++++++- 6 files changed, 109 insertions(+), 19 deletions(-) diff --git a/python/codac/core/__init__.py b/python/codac/core/__init__.py index 6948719f..e8c550b8 100644 --- a/python/codac/core/__init__.py +++ b/python/codac/core/__init__.py @@ -17,21 +17,27 @@ def codac_error(message): class AnalyticFunction: - def __init__(self, args, e): - if isinstance(e, (int,float,Interval,ScalarVar,ScalarExpr)): - self.f = AnalyticFunction_Scalar(args,ScalarExpr(e)) - elif isinstance(e, (Vector,IntervalVector,VectorVar,VectorExpr)): - self.f = AnalyticFunction_Vector(args,VectorExpr(e)) - elif isinstance(e, list): - lst=[] - for e_i in e: - if isinstance(e_i, (int,float,Interval,ScalarVar,ScalarExpr)): - lst.append(ScalarExpr(e_i)) - else: - codac_error("AnalyticFunction: invalid vectorial expression") - self.f = AnalyticFunction_Vector(args,lst) + def __init__(self, args, e=None): + if e: + if isinstance(e, (int,float,Interval,ScalarVar,ScalarExpr)): + self.f = AnalyticFunction_Scalar(args,ScalarExpr(e)) + elif isinstance(e, (Vector,IntervalVector,VectorVar,VectorExpr)): + self.f = AnalyticFunction_Vector(args,VectorExpr(e)) + elif isinstance(e, list): + lst=[] + for e_i in e: + if isinstance(e_i, (int,float,Interval,ScalarVar,ScalarExpr)): + lst.append(ScalarExpr(e_i)) + else: + codac_error("AnalyticFunction: invalid vectorial expression") + self.f = AnalyticFunction_Vector(args,lst) + else: + codac_error("AnalyticFunction: can only build functions from scalar or vector expressions") else: - codac_error("AnalyticFunction: can only build functions from scalar or vector expressions") + if isinstance(args, (AnalyticFunction_Scalar,AnalyticFunction_Vector)): + self.f = args + else: + codac_error("AnalyticFunction: invalid function argument") def input_size(self): return self.f.input_size() @@ -279,6 +285,9 @@ def sampled(self, dt): def primitive(self, y0, t): return SampledTrajectory(self.traj.primitive(y0, t)) + def as_function(self): + return AnalyticFunction(self.traj.as_function()) + # Methods from AnalyticTrajectory: # none @@ -296,6 +305,14 @@ def __init__(self, m): self.traj = SampledTrajectory_Vector(m) else: codac_error("SampledTrajectory: can only build this trajectory from maps of scalar or vector values") + + # Methods from std::map: + + def __setitem__(self, t, y): + self.traj[t] = y + + def __getitem__(self, t): + return self.traj[t] # Methods from TrajectoryBase: @@ -326,6 +343,9 @@ def sampled(self, *args): def primitive(self, y0, t): return SampledTrajectory(self.traj.primitive(y0, t)) + def as_function(self): + return AnalyticFunction(self.traj.as_function()) + # Methods from SampledTrajectory: def nb_samples(self): diff --git a/python/src/core/trajectory/codac2_py_AnalyticTrajectory.cpp b/python/src/core/trajectory/codac2_py_AnalyticTrajectory.cpp index c3a49279..7c05e51c 100644 --- a/python/src/core/trajectory/codac2_py_AnalyticTrajectory.cpp +++ b/python/src/core/trajectory/codac2_py_AnalyticTrajectory.cpp @@ -16,6 +16,7 @@ #include "codac2_py_AnalyticTrajectory_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py): #include "codac2_py_TrajectoryBase_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py): #include "codac2_py_TrajectoryBase.h" +#include "codac2_Trajectory_operator.h" #include "codac2_py_doc.h" using namespace std; diff --git a/python/src/core/trajectory/codac2_py_SampledTrajectory.cpp b/python/src/core/trajectory/codac2_py_SampledTrajectory.cpp index b290da30..ca4b45d2 100644 --- a/python/src/core/trajectory/codac2_py_SampledTrajectory.cpp +++ b/python/src/core/trajectory/codac2_py_SampledTrajectory.cpp @@ -15,6 +15,7 @@ #include "codac2_py_SampledTrajectory_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py): #include "codac2_py_TrajectoryBase_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py): #include "codac2_py_TrajectoryBase.h" +#include "codac2_Trajectory_operator.h" #include "codac2_py_doc.h" using namespace std; @@ -47,6 +48,17 @@ void _export_SampledTrajectory(py::module& m, const string& class_name) SAMPLEDTRAJECTORY_T_SAMPLEDTRAJECTORY_T_SAMPLED_DOUBLE_BOOL_CONST, "dt"_a, "keep_original_values"_a) + .def("__getitem__", [](const SampledTrajectory& x, Index_type index) -> const T& + { + matlab::test_integer(index); + return x.at(matlab::input_index(index)); + }, py::return_value_policy::reference_internal) + + .def("__setitem__", [](SampledTrajectory& x, Index_type index, const T& a) + { + matlab::test_integer(index); + x[matlab::input_index(index)] = a; + }) ; } diff --git a/python/src/core/trajectory/codac2_py_TrajectoryBase.h b/python/src/core/trajectory/codac2_py_TrajectoryBase.h index 9c91c5e9..442f51ac 100644 --- a/python/src/core/trajectory/codac2_py_TrajectoryBase.h +++ b/python/src/core/trajectory/codac2_py_TrajectoryBase.h @@ -84,12 +84,18 @@ void export_TrajectoryBase(py::class_& pyclass) VIRTUAL_SAMPLEDTRAJECTORY_T_TRAJECTORYBASE_T_SAMPLED_DOUBLE_CONST, "dt"_a) - .def("primitive", [](const S& x, const typename S::Type::Scalar& y0, double dt) + .def("primitive", [](const S& x, const typename S::TrajType::Scalar& y0, double dt) { return x.primitive(y0,dt); }, SAMPLEDTRAJECTORY_T_TRAJECTORYBASE_T_PRIMITIVE_CONST_T_REF_DOUBLE_CONST, "y0"_a, "dt"_a) + .def("as_function", [](const S& x) + { + return x.as_function(); + }, + ANALYTICFUNCTION_TYPENAME_VALUETYPE_T_TYPE_TRAJECTORYBASE_T_AS_FUNCTION_CONST) + ; } \ No newline at end of file diff --git a/src/core/trajectory/codac2_TrajectoryBase.h b/src/core/trajectory/codac2_TrajectoryBase.h index e7b8a2d9..7626d037 100644 --- a/src/core/trajectory/codac2_TrajectoryBase.h +++ b/src/core/trajectory/codac2_TrajectoryBase.h @@ -24,7 +24,7 @@ namespace codac2 { public: - using Type = ValueType::Type; + using TrajType = ValueType::Type; TrajectoryBase() { } @@ -39,7 +39,7 @@ namespace codac2 auto nan_value() const { - if constexpr(std::is_same_v::Type,ScalarType>) + if constexpr(std::is_same_v) return std::numeric_limits::quiet_NaN(); else @@ -86,6 +86,6 @@ namespace codac2 } // Implementation in codac2_Trajectory_operator.h - AnalyticFunction::Type> as_function() const; + AnalyticFunction as_function() const; }; } \ No newline at end of file diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.py b/tests/core/trajectory/codac2_tests_SampledTrajectory.py index 62fb8e82..29b30f32 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.py +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.py @@ -9,7 +9,7 @@ import unittest from codac import * -import sys +import sys, math class TestSampledTrajectory(unittest.TestCase): @@ -58,5 +58,56 @@ def tests_SampledTrajectory(self): #DefaultView.draw_trajectory(x, Color.blue()) #DefaultView.draw_trajectory(x_sampled, Color.red()) + # SampledTrajectory as operator (1d case) + + t = ScalarVar() + f = AnalyticFunction( + [t], cos(t) + ) + analytic_traj = AnalyticTrajectory(f, [-math.pi,math.pi]) + sampled_traj = analytic_traj.sampled(1e-2) + g = sampled_traj.as_function() + + h = AnalyticFunction( + [t], g(t) + ) + + t_ = -math.pi + while t_ < math.pi: + self.assertTrue(Approx(h.real_eval(t_)) == math.cos(t_)) + t_=t_+1e-2 + + # SampledTrajectory as operator (nd case) + + t = ScalarVar() + f = AnalyticFunction( + [t], + vec(2*cos(t),sin(2*t)) + ) + + analytic_traj = AnalyticTrajectory(f, [0,5]) + sampled_traj = analytic_traj.sampled(1e-2) + g = sampled_traj.as_function() + + h = AnalyticFunction( + [t], + g(t) + ) + + t_ = 0 + while t_ < 5: + self.assertTrue(Approx(h.real_eval(t_)) == Vector([2*math.cos(t_),math.sin(2*t_)])) + t_=t_+1e-2 + + h = AnalyticFunction( + [t], + [ g(t)[0],g(t)[1] ] + ) + + t_ = 0 + while t_ < 5: + self.assertTrue(Approx(h.real_eval(t_)) == Vector([2*math.cos(t_),math.sin(2*t_)])) + t_=t_+1e-2 + if __name__ == '__main__': unittest.main() \ No newline at end of file From 70ca2dd97f7bacc73f50bd87ed58727ca39378df Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Thu, 26 Dec 2024 18:42:52 +0100 Subject: [PATCH 11/18] [sep] simplifying binding of SepInverse --- python/codac/core/__init__.py | 20 +---------- python/src/core/codac2_py_core.cpp | 3 +- .../analytic/codac2_py_AnalyticFunction.h | 14 ++++++++ .../core/separators/codac2_py_SepInverse.h | 34 ++++++++++++++----- src/core/functions/set/codac2_set_operators.h | 2 +- src/core/separators/codac2_SepInverse.h | 18 ++++++---- .../separators/codac2_tests_SepCartProd.cpp | 4 +-- .../separators/codac2_tests_SepInverse.cpp | 4 +-- .../core/separators/codac2_tests_SepProj.cpp | 2 +- .../separators/codac2_tests_SepTransform.cpp | 2 +- 10 files changed, 59 insertions(+), 44 deletions(-) diff --git a/python/codac/core/__init__.py b/python/codac/core/__init__.py index e8c550b8..3ee1b854 100644 --- a/python/codac/core/__init__.py +++ b/python/codac/core/__init__.py @@ -133,24 +133,6 @@ def copy(self): return self.c.copy() -class SepInverse(Sep): - - def __init__(self, f, y, with_centered_form = True): - Sep.__init__(self, f.input_size()) - if isinstance(f.f, AnalyticFunction_Scalar): - self.s = SepInverse_Interval(f.f,Interval(y),with_centered_form) - elif isinstance(f.f, AnalyticFunction_Vector): - self.s = SepInverse_IntervalVector(f.f,IntervalVector(y),with_centered_form) - else: - codac_error("SepInverse: can only build SepInverse from scalar or vector functions") - - def separate(self,x): - return self.s.separate(x) - - def copy(self): - return super().copy() - - class Approx: def __init__(self, x, eps = float_info.epsilon*10): @@ -209,7 +191,7 @@ def cart_prod(*args): mode = 1 lst.append(arg) - elif isinstance(arg, Sep): + elif isinstance(arg, (Sep,SepBase)): if mode != -1 and mode != 2: codac_error("cart_prod: invalid input arguments, was expecting a " + mode_str[mode] + ", got a separator") mode = 2 diff --git a/python/src/core/codac2_py_core.cpp b/python/src/core/codac2_py_core.cpp index 977560bb..50fb4fb5 100644 --- a/python/src/core/codac2_py_core.cpp +++ b/python/src/core/codac2_py_core.cpp @@ -214,8 +214,7 @@ PYBIND11_MODULE(_core, m) export_SepCtcBoundary(m,py_sep); export_SepCtcPair(m,py_sep); export_SepInter(m,py_sep); - export_SepInverse(m,"SepInverse_Interval",py_sep); - export_SepInverse(m,"SepInverse_IntervalVector",py_sep); + export_SepInverse(m,py_sep); export_SepNot(m,py_sep); export_SepPolygon(m,py_sep); export_SepProj(m,py_sep); diff --git a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h index 8df9ce3f..f1506949 100644 --- a/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h +++ b/python/src/core/functions/analytic/codac2_py_AnalyticFunction.h @@ -98,6 +98,20 @@ AnalyticExprWrapper pyobj_to_ScalarExpr(const py::object& obj) return { nullptr }; } +template +AnalyticFunction cast_to_AnalyticFunction(const py::object& f) +{ + py::object f_ = f.attr("f"); + + if(!f_) + assert_release("cast_function: py::object f has no attribute named 'f'"); + + if(!py::isinstance>(f_)) + assert_release("cast_function: provided analytic function has incorrect type"); + + return f_.cast>(); +} + std::shared_ptr pyobj_to_ExprBase(const py::object& obj) { if(obj) diff --git a/python/src/core/separators/codac2_py_SepInverse.h b/python/src/core/separators/codac2_py_SepInverse.h index d6fcca5e..0ca6a4cf 100644 --- a/python/src/core/separators/codac2_py_SepInverse.h +++ b/python/src/core/separators/codac2_py_SepInverse.h @@ -15,6 +15,7 @@ #include "codac2_py_Sep.h" #include "codac2_py_SepInverse_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py): #include "codac2_py_SepCtcPair_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py): +#include "codac2_py_AnalyticFunction.h" using namespace std; using namespace codac2; @@ -22,27 +23,42 @@ namespace py = pybind11; using namespace pybind11::literals; template -void export_SepInverse(py::module& m, const std::string& export_name, py::class_& pysep) +void export_SepInverse_type(py::class_& exported) { - using D = typename T::Domain; - py::class_> exported(m, export_name.c_str(), pysep, SEPINVERSE_MAIN); - exported - .def(py::init&,const D&,bool>(), - SEPINVERSE_Y_SEPINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CONST_Y_REF_BOOL, + .def(py::init( + [](const py::object& f, const typename T::Domain& y, bool with_centered_form) + { + return std::make_unique(cast_to_AnalyticFunction(f), y, with_centered_form); + } + ), + SEPINVERSE_SEPINVERSE_CONST_ANALYTICFUNCTION_T_REF_CONST_TYPENAME_T_DOMAIN_REF_BOOL, "f"_a, "y"_a, "with_centered_form"_a = true); if constexpr(std::is_same_v) // separators only associated with interval vectors { exported - .def(py::init&,const pySep&,bool>(), - SEPINVERSE_Y_SEPINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_VALUETYPE_Y_TYPE_REF_CONST_S_REF_BOOL, + .def(py::init( + [](const py::object& f, const pySep& s, bool with_centered_form) + { + return std::make_unique(cast_to_AnalyticFunction(f), s, with_centered_form); + } + ), + SEPINVERSE_SEPINVERSE_CONST_ANALYTICFUNCTION_T_REF_CONST_S_REF_BOOL, "f"_a, "s"_a, "with_centered_form"_a = true); } +} + +void export_SepInverse(py::module& m, py::class_& pysep) +{ + py::class_ exported(m, "SepInverse", pysep, SEPINVERSE_MAIN); + + export_SepInverse_type(exported); + export_SepInverse_type(exported); exported - .def("separate", &SepInverse::separate, + .def("separate", &SepInverse::separate, BOXPAIR_SEPCTCPAIR_SEPARATE_CONST_INTERVALVECTOR_REF_CONST, "x"_a) ; diff --git a/src/core/functions/set/codac2_set_operators.h b/src/core/functions/set/codac2_set_operators.h index c897b1aa..f8c29d6b 100644 --- a/src/core/functions/set/codac2_set_operators.h +++ b/src/core/functions/set/codac2_set_operators.h @@ -101,7 +101,7 @@ namespace codac2 static std::shared_ptr create_sep(const AnalyticFunction& f, const std::shared_ptr& s1) { - return std::make_shared>(f,s1); + return std::make_shared(f,s1); } }; diff --git a/src/core/separators/codac2_SepInverse.h b/src/core/separators/codac2_SepInverse.h index ba8c5f8c..a0879cc5 100644 --- a/src/core/separators/codac2_SepInverse.h +++ b/src/core/separators/codac2_SepInverse.h @@ -20,21 +20,25 @@ namespace codac2 { - template class SepInverse : public SepCtcPair { using X = IntervalVector; public: - SepInverse(const AnalyticFunction::Type>& f, const Y& y, bool with_centered_form = true) - : SepCtcPair(CtcInverseNotIn(f,y,with_centered_form), CtcInverse_(f,y,with_centered_form)) + template + SepInverse(const AnalyticFunction& f, const typename T::Domain& y, bool with_centered_form = true) + : SepCtcPair( + CtcInverseNotIn(f,y,with_centered_form), + CtcInverse_(f,y,with_centered_form)) { } - template - requires (std::is_same_v && IsSepBaseOrPtr) - SepInverse(const AnalyticFunction::Type>& f, const S& sep_y, bool with_centered_form = true) - : SepCtcPair(CtcInverseNotIn(f,CtcInner(sep_y),with_centered_form), CtcInverse_(f,CtcOuter(sep_y),with_centered_form)) + template + requires (std::is_same_v && IsSepBaseOrPtr) + SepInverse(const AnalyticFunction& f, const S& sep_y, bool with_centered_form = true) + : SepCtcPair( + CtcInverseNotIn(f,CtcInner(sep_y),with_centered_form), + CtcInverse_(f,CtcOuter(sep_y),with_centered_form)) { } }; } \ No newline at end of file diff --git a/tests/core/separators/codac2_tests_SepCartProd.cpp b/tests/core/separators/codac2_tests_SepCartProd.cpp index 15a76acc..96a53a05 100644 --- a/tests/core/separators/codac2_tests_SepCartProd.cpp +++ b/tests/core/separators/codac2_tests_SepCartProd.cpp @@ -18,8 +18,8 @@ TEST_CASE("SepCartProd") { { VectorVar v(1); - SepInverse s1(AnalyticFunction({v}, v), IntervalVector({{-1,1}})); - SepInverse s2(AnalyticFunction({v}, v), IntervalVector({{5,6}})); + SepInverse s1(AnalyticFunction({v}, v), IntervalVector({{-1,1}})); + SepInverse s2(AnalyticFunction({v}, v), IntervalVector({{5,6}})); { IntervalVector x({{0,8},{5.5,oo}}); diff --git a/tests/core/separators/codac2_tests_SepInverse.cpp b/tests/core/separators/codac2_tests_SepInverse.cpp index 6c55c64a..71ee8fb8 100644 --- a/tests/core/separators/codac2_tests_SepInverse.cpp +++ b/tests/core/separators/codac2_tests_SepInverse.cpp @@ -20,7 +20,7 @@ TEST_CASE("SepInverse") { VectorVar x(2); AnalyticFunction f { {x}, vec(x[0],sqr(x[0]/7.)+sqr(x[1]/3.)) }; - SepInverse s(f, {{0,oo},{-oo,1}}); + SepInverse s(f, {{0,oo},{-oo,1}}); //pave(IntervalVector({{-10,10},{-10,10}}), s, 0.1); @@ -79,7 +79,7 @@ TEST_CASE("SepInverse - other test") { VectorVar x(2); AnalyticFunction f { {x}, vec(sqr(x[0])+sqr(x[1])) }; - SepInverse s(f, {{0,1}}); + SepInverse s(f, {{0,1}}); //pave({{-5,5},{-5,5}}, s, 0.01); diff --git a/tests/core/separators/codac2_tests_SepProj.cpp b/tests/core/separators/codac2_tests_SepProj.cpp index 55309e3b..14849914 100644 --- a/tests/core/separators/codac2_tests_SepProj.cpp +++ b/tests/core/separators/codac2_tests_SepProj.cpp @@ -22,7 +22,7 @@ TEST_CASE("SepProj") { VectorVar x(3); AnalyticFunction f_ellipsoid({x}, 2*sqr(x[0])+x[0]*x[1]+x[0]*x[2]+sqr(x[1])+sqr(x[2])); - SepInverse sep_ellipsoid(f_ellipsoid, {0.7,1}); + SepInverse sep_ellipsoid(f_ellipsoid, {0.7,1}); SepProj sep_proj(sep_ellipsoid, {0,1}, {{0.1,0.2}}); // todo: test with SepProj sep_proj(sep_ellipsoid, {0,1}, {{-oo,oo}}); diff --git a/tests/core/separators/codac2_tests_SepTransform.cpp b/tests/core/separators/codac2_tests_SepTransform.cpp index 2f4b4d60..b3a16256 100644 --- a/tests/core/separators/codac2_tests_SepTransform.cpp +++ b/tests/core/separators/codac2_tests_SepTransform.cpp @@ -20,7 +20,7 @@ TEST_CASE("SepTransform") { { VectorVar x(2); - SepInverse s1(AnalyticFunction({x}, sqr(x[0])+sqr(x[1])), Interval(0,1)); + SepInverse s1(AnalyticFunction({x}, sqr(x[0])+sqr(x[1])), Interval(0,1)); SepTransform s2(s1, AnalyticFunction({x}, vec(x[0]+2,x[1]+2)), AnalyticFunction({x}, vec(x[0]-2,x[1]-2))); From f745eabab6aef238a158893a57f218124d4c183d Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Thu, 26 Dec 2024 18:43:52 +0100 Subject: [PATCH 12/18] [ex] added example "explored_area" (c++/py) for using trajectories in functions --- examples/04_explored_area/CMakeLists.txt | 40 ++++++++++++++++++++++++ examples/04_explored_area/main.cpp | 38 ++++++++++++++++++++++ examples/04_explored_area/main.py | 33 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 examples/04_explored_area/CMakeLists.txt create mode 100644 examples/04_explored_area/main.cpp create mode 100644 examples/04_explored_area/main.py diff --git a/examples/04_explored_area/CMakeLists.txt b/examples/04_explored_area/CMakeLists.txt new file mode 100644 index 00000000..314b49ff --- /dev/null +++ b/examples/04_explored_area/CMakeLists.txt @@ -0,0 +1,40 @@ +# ================================================================== +# codac / basics example - cmake configuration file +# ================================================================== + + cmake_minimum_required(VERSION 3.0.2) + project(codac_example LANGUAGES CXX) + + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Adding IBEX + + # In case you installed IBEX in a local directory, you need + # to specify its path with the CMAKE_PREFIX_PATH option. + # set(CMAKE_PREFIX_PATH "~/ibex-lib/build_install") + + find_package(IBEX REQUIRED) + ibex_init_common() # IBEX should have installed this function + message(STATUS "Found IBEX version ${IBEX_VERSION}") + +# Adding Codac + + # In case you installed Codac in a local directory, you need + # to specify its path with the CMAKE_PREFIX_PATH option. + # set(CMAKE_PREFIX_PATH "~/codac/build_install") + + find_package(CODAC REQUIRED) + message(STATUS "Found Codac version ${CODAC_VERSION}") + +# Compilation + + if(FAST_RELEASE) + add_compile_definitions(FAST_RELEASE) + message(STATUS "You are running Codac in fast release mode. (option -DCMAKE_BUILD_TYPE=Release is required)") + endif() + + add_executable(${PROJECT_NAME} main.cpp) + target_compile_options(${PROJECT_NAME} PUBLIC ${CODAC_CXX_FLAGS}) + target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES} Ibex::ibex) \ No newline at end of file diff --git a/examples/04_explored_area/main.cpp b/examples/04_explored_area/main.cpp new file mode 100644 index 00000000..7271db87 --- /dev/null +++ b/examples/04_explored_area/main.cpp @@ -0,0 +1,38 @@ +// Example: A sampled trajectory, 'sampled_f' (composed of time-stamped positions with +// linear interpolation between them), is first obtained by discretizing an analytical +// expression (the function 'f,' which represents a Lissajous curve) and then appending +// an additional position. This trajectory is subsequently used in another analytical +// expression (function 'h'). The projection of an inverse separator is then employed +// to validate the result. + +#include + +using namespace codac2; + +int main() +{ + ScalarVar t; + AnalyticFunction f { + {t}, + { 2*cos(t), sin(2*t) } + }; + + Interval tdomain(0,5); + auto sampled_f = AnalyticTrajectory(f,tdomain).sampled(0.8); + sampled_f[6] = {0,-1}; + + VectorVar w(3); + auto g = sampled_f.as_function(); + AnalyticFunction h { + {w}, + sqr(w[0]-g(w[2])[0])+sqr(w[1]-g(w[2])[1]) + }; + + SepInverse s_h(h, {0,0.1}); + SepProj s_projh(s_h, {0,1}, {sampled_f.tdomain()}); + + DefaultView::set_window_properties({75,75},{700,700}); + draw_while_paving({{-3,3},{-2,2}}, s_projh, 5e-2); + DefaultView::draw_trajectory(sampled_f); + DefaultView::draw_trajectory(AnalyticTrajectory(f,tdomain), Color::dark_gray()); +} \ No newline at end of file diff --git a/examples/04_explored_area/main.py b/examples/04_explored_area/main.py new file mode 100644 index 00000000..38481654 --- /dev/null +++ b/examples/04_explored_area/main.py @@ -0,0 +1,33 @@ +from codac import * + +# Example: A sampled trajectory, 'sampled_f' (composed of time-stamped positions with +# linear interpolation between them), is first obtained by discretizing an analytical +# expression (the function 'f,' which represents a Lissajous curve) and then appending +# an additional position. This trajectory is subsequently used in another analytical +# expression (function 'h'). The projection of an inverse separator is then employed +# to validate the result. + +t = ScalarVar() +f = AnalyticFunction( + [t], + [ 2*cos(t), sin(2*t) ] +) + +tdomain = [0,5] +sampled_f = AnalyticTrajectory(f,tdomain).sampled(0.8) +sampled_f[6] = [0,-1] + +w = VectorVar(3) +g = sampled_f.as_function() +h = AnalyticFunction( + [w], + sqr(w[0]-g(w[2])[0])+sqr(w[1]-g(w[2])[1]) +) + +s_h = SepInverse(h, [0,0.1]) +s_projh = SepProj(s_h, [0,1], [sampled_f.tdomain()]) + +DefaultView.set_window_properties([75,75],[700,700]) +draw_while_paving([[-3,3],[-2,2]], s_projh, 5e-2) +DefaultView.draw_trajectory(sampled_f) +DefaultView.draw_trajectory(AnalyticTrajectory(f,tdomain), Color.dark_gray()) \ No newline at end of file From 2a0391a5254dd5318991314cf2c5a25cd3ee8816 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Fri, 27 Dec 2024 17:47:12 +0100 Subject: [PATCH 13/18] [pr] minor corrections --- tests/core/trajectory/codac2_tests_SampledTrajectory.cpp | 4 ++-- tests/core/trajectory/codac2_tests_SampledTrajectory.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp index ab2695cb..008cbd64 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp @@ -66,13 +66,13 @@ TEST_CASE("SampledTrajectory as operator (1d case)") { ScalarVar t; AnalyticFunction f { {t}, cos(t) }; - AnalyticTrajectory analytic_traj(f, {-M_PI,M_PI}); + AnalyticTrajectory analytic_traj(f, {-pi,pi}); auto sampled_traj = analytic_traj.sampled(1e-2); auto g = sampled_traj.as_function(); AnalyticFunction h { {t}, g(t) }; - for(double t = -M_PI ; t < M_PI ; t+=1e-2) + for(double t = -pi ; t < pi ; t+=1e-2) CHECK(Approx(h.real_eval(t)) == cos(t)); } diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.py b/tests/core/trajectory/codac2_tests_SampledTrajectory.py index 29b30f32..7d3cdf91 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.py +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.py @@ -74,7 +74,7 @@ def tests_SampledTrajectory(self): t_ = -math.pi while t_ < math.pi: - self.assertTrue(Approx(h.real_eval(t_)) == math.cos(t_)) + self.assertTrue(Approx(h.real_eval(t_),1e-8) == math.cos(t_)) t_=t_+1e-2 # SampledTrajectory as operator (nd case) From 834e37299655e67db5327c7dd86ba62d9874b805 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Fri, 27 Dec 2024 18:09:53 +0100 Subject: [PATCH 14/18] [math] using pi from GAOL as default value --- src/core/tools/codac2_math.h | 5 +- .../3rd/vibes/codac2_Figure2D_VIBes.cpp | 8 ++-- src/graphics/figures/codac2_Figure2D.cpp | 2 +- .../interval/codac2_tests_Interval_bwd.cpp | 48 +++++++++---------- .../codac2_tests_AnalyticFunction.cpp | 36 +++++++------- .../codac2_tests_SampledTrajectory.cpp | 1 + 6 files changed, 51 insertions(+), 49 deletions(-) diff --git a/src/core/tools/codac2_math.h b/src/core/tools/codac2_math.h index ba4cae14..9094dc9e 100644 --- a/src/core/tools/codac2_math.h +++ b/src/core/tools/codac2_math.h @@ -13,5 +13,8 @@ namespace codac2 { - constexpr double pi = std::numbers::pi; // Need C++20 + // As long as GAOL defines pi in common namespace, + // we use it as default pi value instead of the pi + // from the standard library. + //constexpr double pi = std::numbers::pi; // Need C++20 } \ No newline at end of file diff --git a/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp b/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp index 582e5a97..bdeb6c36 100644 --- a/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp +++ b/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp @@ -118,28 +118,28 @@ void Figure2D_VIBes::draw_pie(const Vector& c, const Interval& r, const Interval assert(_fig.size() <= c.size()); assert(r.lb() >= 0.); // Corrected a bug in VIBEs in case of r=[..,oo] (the pie disappears when zoomed in) - vibes::drawPie(c[i()],c[j()], r.lb(),(r.ub()>1e5?1e5:r.ub()), 180.*theta.lb()/codac2::pi,180.*theta.ub()/codac2::pi, to_vibes_style(s), _params); + vibes::drawPie(c[i()],c[j()], r.lb(),(r.ub()>1e5?1e5:r.ub()), 180.*theta.lb()/pi,180.*theta.ub()/pi, to_vibes_style(s), _params); } void Figure2D_VIBes::draw_ellipse(const Vector& c, const Vector& ab, double theta, const StyleProperties& s) { assert(c.size() == 2); assert(ab.size() == 2); - vibes::drawEllipse(c[0],c[1], ab[0],ab[1], 180.*theta/codac2::pi, to_vibes_style(s), _params); + vibes::drawEllipse(c[0],c[1], ab[0],ab[1], 180.*theta/pi, to_vibes_style(s), _params); } void Figure2D_VIBes::draw_tank(const Vector& x, float size, const StyleProperties& s) { assert(_fig.size() <= x.size()+1); assert(j()+1 < x.size()); - vibes::drawTank(x[i()],x[j()],180.*x[j()+1]/codac2::pi, size, to_vibes_style(s), _params); + vibes::drawTank(x[i()],x[j()],180.*x[j()+1]/pi, size, to_vibes_style(s), _params); } void Figure2D_VIBes::draw_AUV(const Vector& x, float size, const StyleProperties& s) { assert(_fig.size() <= x.size()+1); assert(j()+1 < x.size()); - vibes::drawAUV(x[i()],x[j()],180.*x[j()+1]/codac2::pi, size, to_vibes_style(s), _params); + vibes::drawAUV(x[i()],x[j()],180.*x[j()+1]/pi, size, to_vibes_style(s), _params); } string Figure2D_VIBes::to_vibes_style(const StyleProperties& s) diff --git a/src/graphics/figures/codac2_Figure2D.cpp b/src/graphics/figures/codac2_Figure2D.cpp index bb18871d..0320fd71 100644 --- a/src/graphics/figures/codac2_Figure2D.cpp +++ b/src/graphics/figures/codac2_Figure2D.cpp @@ -178,7 +178,7 @@ void Figure2D::draw_pie(const Vector& c, const Interval& r, const Interval& thet Interval theta_(theta); if(theta.is_unbounded()) - theta_ = Interval(0,2.*codac2::pi); + theta_ = Interval(0,2.*pi); Interval r_(r); if(r.is_unbounded()) diff --git a/tests/core/domains/interval/codac2_tests_Interval_bwd.cpp b/tests/core/domains/interval/codac2_tests_Interval_bwd.cpp index 4f2715c7..dbfdac1e 100644 --- a/tests/core/domains/interval/codac2_tests_Interval_bwd.cpp +++ b/tests/core/domains/interval/codac2_tests_Interval_bwd.cpp @@ -22,8 +22,6 @@ using namespace std; using namespace codac2; -#define PI codac2::pi - const double MAX_DOUBLE = std::numeric_limits::max(); void CHECK_bwd_trigo(const Interval& y, const Interval& x, const Interval& expected_x) @@ -263,25 +261,25 @@ TEST_CASE("Interval bwd operations") Interval a, y; - a = Interval(PI/6.,PI/3.); y = Interval(.5,10.); x = Interval(.5,2.); + a = Interval(pi/6.,pi/3.); y = Interval(.5,10.); x = Interval(.5,2.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(.5,2.*sqrt(3.))); CHECK(Approx(x) == Interval(.5,2.)); - a = Interval(PI/6.,PI/3.); y = Interval(.5,2.); x = Interval(.5,10.); + a = Interval(pi/6.,pi/3.); y = Interval(.5,2.); x = Interval(.5,10.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(.5,2.)); CHECK(Approx(x) == Interval(.5,2.*sqrt(3.))); - a = Interval(-PI/4.,PI/4.); y = Interval(1.,2.); x = Interval(.5,2.); + a = Interval(-pi/4.,pi/4.); y = Interval(1.,2.); x = Interval(.5,2.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(1.,2.)); CHECK(Approx(x) == Interval(1.,2.)); - a = Interval(-PI/2.,0.); y = Interval(.5,2.); x = Interval(.5,10.); + a = Interval(-pi/2.,0.); y = Interval(.5,2.); x = Interval(.5,10.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval::empty()); CHECK(Approx(x) == Interval::empty()); - a = Interval(2.*PI,3.*PI); y = Interval(-.5,2.); x = Interval(.5,10.); + a = Interval(2.*pi,3.*pi); y = Interval(-.5,2.); x = Interval(.5,10.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval::empty()); CHECK(Approx(x) == Interval::empty()); - a = Interval(2*PI/3.,5.*PI/6.); y = Interval(0.,100.); x = Interval(-20.,-sqrt(3.)/2.); + a = Interval(2*pi/3.,5.*pi/6.); y = Interval(0.,100.); x = Interval(-20.,-sqrt(3.)/2.); bwd_atan2(a,y,x); CHECK(Approx(y,1e-10) == Interval(.5,20.*sqrt(3.))); CHECK(Approx(x) == Interval(-20.,-sqrt(3.)/2)); - a = Interval(-3*PI/4.,-2*PI/3.); y = Interval(-sqrt(3.)/2.,2.); x = Interval(-sqrt(2.)/2.,0.); + a = Interval(-3*pi/4.,-2*pi/3.); y = Interval(-sqrt(3.)/2.,2.); x = Interval(-sqrt(2.)/2.,0.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(-sqrt(3.)/2.,0.)); CHECK(Approx(x) == Interval(-sqrt(2.)/2.,0.)); - a = Interval(-3*PI/4.,-2*PI/3.); y = Interval(-sqrt(3.)/2.,2.); x = Interval(-1.,-.5); + a = Interval(-3*pi/4.,-2*pi/3.); y = Interval(-sqrt(3.)/2.,2.); x = Interval(-1.,-.5); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(-sqrt(3.)/2.,-.5)); CHECK(Approx(x) == Interval(-sqrt(3.)/2.,-.5)); - a = Interval(-3*PI/4.,-PI/4.); y = Interval(-5.,-.5); x = Interval(-oo,oo); + a = Interval(-3*pi/4.,-pi/4.); y = Interval(-5.,-.5); x = Interval(-oo,oo); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(-5.,-.5)); CHECK(Approx(x) == Interval(-5.,5.)); - a = Interval(-PI/3.,PI/4.); y = Interval(-oo,oo); x = Interval(sqrt(3.)/2.); + a = Interval(-pi/3.,pi/4.); y = Interval(-oo,oo); x = Interval(sqrt(3.)/2.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(-1.5,sqrt(3.)/2.)); CHECK(Approx(x) == Interval(sqrt(3.)/2.)); a = Interval::half_pi(); y = Interval(1); x = 0.; bwd_atan2(a,y,x); CHECK(Approx(y) == 1.); CHECK(Approx(x) == 0.); @@ -294,15 +292,15 @@ TEST_CASE("Interval bwd operations") x = Interval(-1,5); bwd_sqrt(Interval(2,5), x); CHECK(x == Interval(4,5)); x = Interval(-oo,oo); bwd_sqrt(Interval(-4,-2), x); CHECK(x == Interval::empty()); - x = Interval(-1.,3.); bwd_atan(Interval(0.,PI/6.),x); CHECK(x == tan(Interval(0.,PI/6.))); - x = Interval(0,5*PI/2.0); bwd_atan(Interval(-PI,1.5),x); CHECK(x == Interval(0,5*PI/2.0)); - x = Interval(.2,.5); bwd_atan(Interval(0.,PI/6.),x); CHECK(x == Interval(.2,.5)); - x = Interval(-100,100); bwd_atan(Interval(-PI/2-0.1,PI/2+0.1),x); CHECK(x == Interval(-100,100)); - x = Interval(-100,100); bwd_atan(Interval(PI/2+0.1,PI),x); CHECK(x == Interval::empty()); - x = Interval(-100,100); bwd_atan(Interval(-PI,-PI/2-0.1),x); CHECK(x == Interval::empty()); + x = Interval(-1.,3.); bwd_atan(Interval(0.,pi/6.),x); CHECK(x == tan(Interval(0.,pi/6.))); + x = Interval(0,5*pi/2.0); bwd_atan(Interval(-pi,1.5),x); CHECK(x == Interval(0,5*pi/2.0)); + x = Interval(.2,.5); bwd_atan(Interval(0.,pi/6.),x); CHECK(x == Interval(.2,.5)); + x = Interval(-100,100); bwd_atan(Interval(-pi/2-0.1,pi/2+0.1),x); CHECK(x == Interval(-100,100)); + x = Interval(-100,100); bwd_atan(Interval(pi/2+0.1,pi),x); CHECK(x == Interval::empty()); + x = Interval(-100,100); bwd_atan(Interval(-pi,-pi/2-0.1),x); CHECK(x == Interval::empty()); - x = Interval(-oo,oo); bwd_atan(Interval(-PI/4,PI/2.), x); CHECK(x.lb() == -1); CHECK(x.ub() > 1000); - x = Interval(-oo,oo); bwd_atan(Interval(-PI/2,PI/4.), x); CHECK(x.ub() == +1); CHECK(x.lb() < -1000); + x = Interval(-oo,oo); bwd_atan(Interval(-pi/4,pi/2.), x); CHECK(x.lb() == -1); CHECK(x.ub() > 1000); + x = Interval(-oo,oo); bwd_atan(Interval(-pi/2,pi/4.), x); CHECK(x.ub() == +1); CHECK(x.lb() < -1000); CHECK_bwd_add(Interval(1,3),Interval(1,2),Interval(-10,5),Interval(1,2),Interval(-1,2)); CHECK_bwd_add(Interval::empty(),Interval(0.1,2.0),Interval(-10,2),Interval::empty(),Interval::empty()); @@ -319,11 +317,11 @@ TEST_CASE("Interval bwd operations") CHECK_bwd_imod(3.,Interval(3.,5.),Interval(1.,2.),Interval(4.,5.),Interval(1.,2.)); CHECK_bwd_imod(2.,Interval(7.,8.),Interval(.5,2.),Interval(7.,8.),Interval(1.,2.)); CHECK_bwd_imod(2.,Interval(7.,8.),Interval(0.,2.),Interval(7.,8.),Interval(0.,2.)); - CHECK_bwd_imod(2.*PI,Interval(2.*PI,3.*PI),Interval(PI/6,PI/2.),Interval(13.*PI/6.,5.*PI/2.),Interval(PI/6,PI/2.)); - CHECK_bwd_imod(2.*PI,Interval(3.*PI,4.*PI),Interval(PI/3,PI/2.),Interval::empty(),Interval::empty()); - CHECK_bwd_imod(2.*PI,Interval(3.*PI,4.*PI),Interval(0.,PI/2.),Interval(4*PI),Interval(0.)); - CHECK_bwd_imod(2.*PI,Interval(2.*PI,4.*PI),Interval(-PI/6,PI/2.),Interval(2.*PI,4.*PI),Interval(-PI/6,PI/2.)); - CHECK_bwd_imod(2.*PI,Interval(7.*PI/4.,8.*PI/3),Interval(-PI/2,PI/2.),Interval(7.*PI/4.,5.*PI/2.),Interval(-PI/4,PI/2.)); + CHECK_bwd_imod(2.*pi,Interval(2.*pi,3.*pi),Interval(pi/6,pi/2.),Interval(13.*pi/6.,5.*pi/2.),Interval(pi/6,pi/2.)); + CHECK_bwd_imod(2.*pi,Interval(3.*pi,4.*pi),Interval(pi/3,pi/2.),Interval::empty(),Interval::empty()); + CHECK_bwd_imod(2.*pi,Interval(3.*pi,4.*pi),Interval(0.,pi/2.),Interval(4*pi),Interval(0.)); + CHECK_bwd_imod(2.*pi,Interval(2.*pi,4.*pi),Interval(-pi/6,pi/2.),Interval(2.*pi,4.*pi),Interval(-pi/6,pi/2.)); + CHECK_bwd_imod(2.*pi,Interval(7.*pi/4.,8.*pi/3),Interval(-pi/2,pi/2.),Interval(7.*pi/4.,5.*pi/2.),Interval(-pi/4,pi/2.)); x = Interval(-oo,oo); bwd_floor(Interval::empty(),x); CHECK(x == Interval::empty()); x = Interval(-oo,-0.000001); bwd_floor(Interval(-oo,-1),x); CHECK(x == Interval(-oo,-0.000001)); diff --git a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp index 47abb017..4ba9ad3d 100644 --- a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp +++ b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp @@ -148,47 +148,47 @@ TEST_CASE("AnalyticFunction") //.def(py::self + py::self); CHECK(Approx(AnalyticFunction({x1}, cos(x1)+cos(x1)).eval(m, Interval(0.))) == Interval(2.)); //.def("__add__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)+x1).eval(m, codac2::pi)) == codac2::pi-1); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)+x1).eval(m, pi)) == pi-1); //.def("__radd__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, x1+cos(x1)).eval(m, codac2::pi)) == codac2::pi-1); + CHECK(Approx(AnalyticFunction({x1}, x1+cos(x1)).eval(m, pi)) == pi-1); //.def("__add__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)+Interval(10.)).eval(m, codac2::pi)) == Interval(9)); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)+Interval(10.)).eval(m, pi)) == Interval(9)); //.def("__radd__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, 10+cos(x1)).eval(m, codac2::pi)) == Interval(9)); + CHECK(Approx(AnalyticFunction({x1}, 10+cos(x1)).eval(m, pi)) == Interval(9)); //.def(- py::self); CHECK(Approx(AnalyticFunction({x1}, -cos(x1)).eval(m, Interval(0.))) == Interval(-1.)); //.def(py::self - py::self); CHECK(Approx(AnalyticFunction({x1}, cos(x1)-cos(x1)).eval(m, Interval(0.))) == Interval(0.)); //.def("__sub__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)-x1).eval(m, codac2::pi)) == -codac2::pi-1); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)-x1).eval(m, pi)) == -pi-1); //.def("__rsub__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, x1-cos(x1)).eval(m, codac2::pi)) == codac2::pi+1); + CHECK(Approx(AnalyticFunction({x1}, x1-cos(x1)).eval(m, pi)) == pi+1); //.def("__sub__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)-Interval(10.)).eval(m, codac2::pi)) == -Interval(11)); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)-Interval(10.)).eval(m, pi)) == -Interval(11)); //.def("__rsub__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, 10-cos(x1)).eval(m, codac2::pi)) == Interval(11)); + CHECK(Approx(AnalyticFunction({x1}, 10-cos(x1)).eval(m, pi)) == Interval(11)); //.def(py::self * py::self); CHECK(Approx(AnalyticFunction({x1}, cos(x1)*cos(x1)).eval(m, Interval(0.))) == Interval(1.)); //.def("__mul__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)*x1).eval(m, codac2::pi)) == -1*codac2::pi); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)*x1).eval(m, pi)) == -1*pi); //.def("__rmul__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, x1*cos(x1)).eval(m, codac2::pi)) == -1*codac2::pi); + CHECK(Approx(AnalyticFunction({x1}, x1*cos(x1)).eval(m, pi)) == -1*pi); //.def("__mul__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)*Interval(10.)).eval(m, codac2::pi),1e-9) == -Interval(10)); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)*Interval(10.)).eval(m, pi),1e-9) == -Interval(10)); //.def("__rmul__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, Interval(10.)*cos(x1)).eval(m, codac2::pi),1e-9) == -10); + CHECK(Approx(AnalyticFunction({x1}, Interval(10.)*cos(x1)).eval(m, pi),1e-9) == -10); //.def("__mul__", {}(const ScalarExpr& e1, const VectorExpr& e2); - CHECK(Approx(AnalyticFunction({v1,v2}, cos(v1[0])*(v2+v2)).eval(m, Vector({codac2::pi,-1}),Vector({2,3})),1e-9) == IntervalVector({-4,-6})); + CHECK(Approx(AnalyticFunction({v1,v2}, cos(v1[0])*(v2+v2)).eval(m, Vector({pi,-1}),Vector({2,3})),1e-9) == IntervalVector({-4,-6})); //.def("__truediv__", {}(const ScalarExpr& e1, const ScalarExpr& e2); CHECK(Approx(AnalyticFunction({x1}, cos(x1)/cos(x1)).eval(m, Interval(0.))) == Interval(1.)); //.def("__truediv__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)/x1).eval(m, codac2::pi)) == -1/codac2::pi); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)/x1).eval(m, pi)) == -1/pi); //.def("__rtruediv__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, x1/cos(x1)).eval(m, codac2::pi)) == -codac2::pi); + CHECK(Approx(AnalyticFunction({x1}, x1/cos(x1)).eval(m, pi)) == -pi); //.def("__truediv__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)/Interval(4.)).eval(m, codac2::pi)) == -1./4); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)/Interval(4.)).eval(m, pi)) == -1./4); //.def("__rtruediv__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, 4./cos(x1)).eval(m, codac2::pi)) == -4); + CHECK(Approx(AnalyticFunction({x1}, 4./cos(x1)).eval(m, pi)) == -4); // ======> VectorExpr @@ -218,7 +218,7 @@ TEST_CASE("AnalyticFunction") //.def("__rsub__", {}(const VectorExpr& e1, const IntervalVector& e2); CHECK(Approx(AnalyticFunction({v1,v2}, Vector({1,5})-(v1-v2)).eval(m, IntervalVector({2,3}),Vector({1,5}))) == IntervalVector({0,7})); //.def("__rmul__", {}(const VectorExpr& e1, const ScalarExpr& e2); - CHECK(Approx(AnalyticFunction({v1,v2}, cos(v1[0])*(v2+v2)).eval(m, Vector({codac2::pi,-1}),Vector({2,3})),1e-9) == IntervalVector({-4,-6})); + CHECK(Approx(AnalyticFunction({v1,v2}, cos(v1[0])*(v2+v2)).eval(m, Vector({pi,-1}),Vector({2,3})),1e-9) == IntervalVector({-4,-6})); //.def("__rmul__", {}(const VectorExpr& e1, const ScalarVar& e2); CHECK(Approx(AnalyticFunction({x1}, x1*vec(3*x1,2*x1)).eval(m, 3),1e-9) == IntervalVector({27,18})); } diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp index 008cbd64..de92caf1 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using namespace std; using namespace codac2; From c9bc8f65713625738fd3cb55465488b9192e4815 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Fri, 27 Dec 2024 18:53:51 +0100 Subject: [PATCH 15/18] [math] missing include --- src/core/tools/codac2_math.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/tools/codac2_math.h b/src/core/tools/codac2_math.h index 9094dc9e..b747447b 100644 --- a/src/core/tools/codac2_math.h +++ b/src/core/tools/codac2_math.h @@ -9,7 +9,8 @@ #pragma once -#include +//#include +#include <3rd/gaol/gaol_port.h> namespace codac2 { From 6ec280bb9341c345fc547e789e95756e920441ed Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Fri, 27 Dec 2024 19:30:50 +0100 Subject: [PATCH 16/18] [math] redefining PI --- src/core/tools/codac2_math.h | 8 +--- .../3rd/vibes/codac2_Figure2D_VIBes.cpp | 8 ++-- src/graphics/figures/codac2_Figure2D.cpp | 2 +- .../interval/codac2_tests_Interval_bwd.cpp | 46 +++++++++---------- .../codac2_tests_AnalyticFunction.cpp | 36 +++++++-------- .../codac2_tests_SampledTrajectory.cpp | 4 +- 6 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/core/tools/codac2_math.h b/src/core/tools/codac2_math.h index b747447b..4ee59b7a 100644 --- a/src/core/tools/codac2_math.h +++ b/src/core/tools/codac2_math.h @@ -9,13 +9,9 @@ #pragma once -//#include -#include <3rd/gaol/gaol_port.h> +#include namespace codac2 { - // As long as GAOL defines pi in common namespace, - // we use it as default pi value instead of the pi - // from the standard library. - //constexpr double pi = std::numbers::pi; // Need C++20 + constexpr double PI = std::numbers::pi; // Need C++20 } \ No newline at end of file diff --git a/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp b/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp index bdeb6c36..42aba5d2 100644 --- a/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp +++ b/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp @@ -118,28 +118,28 @@ void Figure2D_VIBes::draw_pie(const Vector& c, const Interval& r, const Interval assert(_fig.size() <= c.size()); assert(r.lb() >= 0.); // Corrected a bug in VIBEs in case of r=[..,oo] (the pie disappears when zoomed in) - vibes::drawPie(c[i()],c[j()], r.lb(),(r.ub()>1e5?1e5:r.ub()), 180.*theta.lb()/pi,180.*theta.ub()/pi, to_vibes_style(s), _params); + vibes::drawPie(c[i()],c[j()], r.lb(),(r.ub()>1e5?1e5:r.ub()), 180.*theta.lb()/PI,180.*theta.ub()/PI, to_vibes_style(s), _params); } void Figure2D_VIBes::draw_ellipse(const Vector& c, const Vector& ab, double theta, const StyleProperties& s) { assert(c.size() == 2); assert(ab.size() == 2); - vibes::drawEllipse(c[0],c[1], ab[0],ab[1], 180.*theta/pi, to_vibes_style(s), _params); + vibes::drawEllipse(c[0],c[1], ab[0],ab[1], 180.*theta/PI, to_vibes_style(s), _params); } void Figure2D_VIBes::draw_tank(const Vector& x, float size, const StyleProperties& s) { assert(_fig.size() <= x.size()+1); assert(j()+1 < x.size()); - vibes::drawTank(x[i()],x[j()],180.*x[j()+1]/pi, size, to_vibes_style(s), _params); + vibes::drawTank(x[i()],x[j()],180.*x[j()+1]/PI, size, to_vibes_style(s), _params); } void Figure2D_VIBes::draw_AUV(const Vector& x, float size, const StyleProperties& s) { assert(_fig.size() <= x.size()+1); assert(j()+1 < x.size()); - vibes::drawAUV(x[i()],x[j()],180.*x[j()+1]/pi, size, to_vibes_style(s), _params); + vibes::drawAUV(x[i()],x[j()],180.*x[j()+1]/PI, size, to_vibes_style(s), _params); } string Figure2D_VIBes::to_vibes_style(const StyleProperties& s) diff --git a/src/graphics/figures/codac2_Figure2D.cpp b/src/graphics/figures/codac2_Figure2D.cpp index 0320fd71..a80d6344 100644 --- a/src/graphics/figures/codac2_Figure2D.cpp +++ b/src/graphics/figures/codac2_Figure2D.cpp @@ -178,7 +178,7 @@ void Figure2D::draw_pie(const Vector& c, const Interval& r, const Interval& thet Interval theta_(theta); if(theta.is_unbounded()) - theta_ = Interval(0,2.*pi); + theta_ = Interval(0,2.*PI); Interval r_(r); if(r.is_unbounded()) diff --git a/tests/core/domains/interval/codac2_tests_Interval_bwd.cpp b/tests/core/domains/interval/codac2_tests_Interval_bwd.cpp index dbfdac1e..4a37fcc3 100644 --- a/tests/core/domains/interval/codac2_tests_Interval_bwd.cpp +++ b/tests/core/domains/interval/codac2_tests_Interval_bwd.cpp @@ -261,25 +261,25 @@ TEST_CASE("Interval bwd operations") Interval a, y; - a = Interval(pi/6.,pi/3.); y = Interval(.5,10.); x = Interval(.5,2.); + a = Interval(PI/6.,PI/3.); y = Interval(.5,10.); x = Interval(.5,2.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(.5,2.*sqrt(3.))); CHECK(Approx(x) == Interval(.5,2.)); - a = Interval(pi/6.,pi/3.); y = Interval(.5,2.); x = Interval(.5,10.); + a = Interval(PI/6.,PI/3.); y = Interval(.5,2.); x = Interval(.5,10.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(.5,2.)); CHECK(Approx(x) == Interval(.5,2.*sqrt(3.))); - a = Interval(-pi/4.,pi/4.); y = Interval(1.,2.); x = Interval(.5,2.); + a = Interval(-PI/4.,PI/4.); y = Interval(1.,2.); x = Interval(.5,2.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(1.,2.)); CHECK(Approx(x) == Interval(1.,2.)); - a = Interval(-pi/2.,0.); y = Interval(.5,2.); x = Interval(.5,10.); + a = Interval(-PI/2.,0.); y = Interval(.5,2.); x = Interval(.5,10.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval::empty()); CHECK(Approx(x) == Interval::empty()); - a = Interval(2.*pi,3.*pi); y = Interval(-.5,2.); x = Interval(.5,10.); + a = Interval(2.*PI,3.*PI); y = Interval(-.5,2.); x = Interval(.5,10.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval::empty()); CHECK(Approx(x) == Interval::empty()); - a = Interval(2*pi/3.,5.*pi/6.); y = Interval(0.,100.); x = Interval(-20.,-sqrt(3.)/2.); + a = Interval(2*PI/3.,5.*PI/6.); y = Interval(0.,100.); x = Interval(-20.,-sqrt(3.)/2.); bwd_atan2(a,y,x); CHECK(Approx(y,1e-10) == Interval(.5,20.*sqrt(3.))); CHECK(Approx(x) == Interval(-20.,-sqrt(3.)/2)); - a = Interval(-3*pi/4.,-2*pi/3.); y = Interval(-sqrt(3.)/2.,2.); x = Interval(-sqrt(2.)/2.,0.); + a = Interval(-3*PI/4.,-2*PI/3.); y = Interval(-sqrt(3.)/2.,2.); x = Interval(-sqrt(2.)/2.,0.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(-sqrt(3.)/2.,0.)); CHECK(Approx(x) == Interval(-sqrt(2.)/2.,0.)); - a = Interval(-3*pi/4.,-2*pi/3.); y = Interval(-sqrt(3.)/2.,2.); x = Interval(-1.,-.5); + a = Interval(-3*PI/4.,-2*PI/3.); y = Interval(-sqrt(3.)/2.,2.); x = Interval(-1.,-.5); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(-sqrt(3.)/2.,-.5)); CHECK(Approx(x) == Interval(-sqrt(3.)/2.,-.5)); - a = Interval(-3*pi/4.,-pi/4.); y = Interval(-5.,-.5); x = Interval(-oo,oo); + a = Interval(-3*PI/4.,-PI/4.); y = Interval(-5.,-.5); x = Interval(-oo,oo); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(-5.,-.5)); CHECK(Approx(x) == Interval(-5.,5.)); - a = Interval(-pi/3.,pi/4.); y = Interval(-oo,oo); x = Interval(sqrt(3.)/2.); + a = Interval(-PI/3.,PI/4.); y = Interval(-oo,oo); x = Interval(sqrt(3.)/2.); bwd_atan2(a,y,x); CHECK(Approx(y) == Interval(-1.5,sqrt(3.)/2.)); CHECK(Approx(x) == Interval(sqrt(3.)/2.)); a = Interval::half_pi(); y = Interval(1); x = 0.; bwd_atan2(a,y,x); CHECK(Approx(y) == 1.); CHECK(Approx(x) == 0.); @@ -292,15 +292,15 @@ TEST_CASE("Interval bwd operations") x = Interval(-1,5); bwd_sqrt(Interval(2,5), x); CHECK(x == Interval(4,5)); x = Interval(-oo,oo); bwd_sqrt(Interval(-4,-2), x); CHECK(x == Interval::empty()); - x = Interval(-1.,3.); bwd_atan(Interval(0.,pi/6.),x); CHECK(x == tan(Interval(0.,pi/6.))); - x = Interval(0,5*pi/2.0); bwd_atan(Interval(-pi,1.5),x); CHECK(x == Interval(0,5*pi/2.0)); - x = Interval(.2,.5); bwd_atan(Interval(0.,pi/6.),x); CHECK(x == Interval(.2,.5)); - x = Interval(-100,100); bwd_atan(Interval(-pi/2-0.1,pi/2+0.1),x); CHECK(x == Interval(-100,100)); - x = Interval(-100,100); bwd_atan(Interval(pi/2+0.1,pi),x); CHECK(x == Interval::empty()); - x = Interval(-100,100); bwd_atan(Interval(-pi,-pi/2-0.1),x); CHECK(x == Interval::empty()); + x = Interval(-1.,3.); bwd_atan(Interval(0.,PI/6.),x); CHECK(x == tan(Interval(0.,PI/6.))); + x = Interval(0,5*PI/2.0); bwd_atan(Interval(-PI,1.5),x); CHECK(x == Interval(0,5*PI/2.0)); + x = Interval(.2,.5); bwd_atan(Interval(0.,PI/6.),x); CHECK(x == Interval(.2,.5)); + x = Interval(-100,100); bwd_atan(Interval(-PI/2-0.1,PI/2+0.1),x); CHECK(x == Interval(-100,100)); + x = Interval(-100,100); bwd_atan(Interval(PI/2+0.1,PI),x); CHECK(x == Interval::empty()); + x = Interval(-100,100); bwd_atan(Interval(-PI,-PI/2-0.1),x); CHECK(x == Interval::empty()); - x = Interval(-oo,oo); bwd_atan(Interval(-pi/4,pi/2.), x); CHECK(x.lb() == -1); CHECK(x.ub() > 1000); - x = Interval(-oo,oo); bwd_atan(Interval(-pi/2,pi/4.), x); CHECK(x.ub() == +1); CHECK(x.lb() < -1000); + x = Interval(-oo,oo); bwd_atan(Interval(-PI/4,PI/2.), x); CHECK(x.lb() == -1); CHECK(x.ub() > 1000); + x = Interval(-oo,oo); bwd_atan(Interval(-PI/2,PI/4.), x); CHECK(x.ub() == +1); CHECK(x.lb() < -1000); CHECK_bwd_add(Interval(1,3),Interval(1,2),Interval(-10,5),Interval(1,2),Interval(-1,2)); CHECK_bwd_add(Interval::empty(),Interval(0.1,2.0),Interval(-10,2),Interval::empty(),Interval::empty()); @@ -317,11 +317,11 @@ TEST_CASE("Interval bwd operations") CHECK_bwd_imod(3.,Interval(3.,5.),Interval(1.,2.),Interval(4.,5.),Interval(1.,2.)); CHECK_bwd_imod(2.,Interval(7.,8.),Interval(.5,2.),Interval(7.,8.),Interval(1.,2.)); CHECK_bwd_imod(2.,Interval(7.,8.),Interval(0.,2.),Interval(7.,8.),Interval(0.,2.)); - CHECK_bwd_imod(2.*pi,Interval(2.*pi,3.*pi),Interval(pi/6,pi/2.),Interval(13.*pi/6.,5.*pi/2.),Interval(pi/6,pi/2.)); - CHECK_bwd_imod(2.*pi,Interval(3.*pi,4.*pi),Interval(pi/3,pi/2.),Interval::empty(),Interval::empty()); - CHECK_bwd_imod(2.*pi,Interval(3.*pi,4.*pi),Interval(0.,pi/2.),Interval(4*pi),Interval(0.)); - CHECK_bwd_imod(2.*pi,Interval(2.*pi,4.*pi),Interval(-pi/6,pi/2.),Interval(2.*pi,4.*pi),Interval(-pi/6,pi/2.)); - CHECK_bwd_imod(2.*pi,Interval(7.*pi/4.,8.*pi/3),Interval(-pi/2,pi/2.),Interval(7.*pi/4.,5.*pi/2.),Interval(-pi/4,pi/2.)); + CHECK_bwd_imod(2.*PI,Interval(2.*PI,3.*PI),Interval(PI/6,PI/2.),Interval(13.*PI/6.,5.*PI/2.),Interval(PI/6,PI/2.)); + CHECK_bwd_imod(2.*PI,Interval(3.*PI,4.*PI),Interval(PI/3,PI/2.),Interval::empty(),Interval::empty()); + CHECK_bwd_imod(2.*PI,Interval(3.*PI,4.*PI),Interval(0.,PI/2.),Interval(4*PI),Interval(0.)); + CHECK_bwd_imod(2.*PI,Interval(2.*PI,4.*PI),Interval(-PI/6,PI/2.),Interval(2.*PI,4.*PI),Interval(-PI/6,PI/2.)); + CHECK_bwd_imod(2.*PI,Interval(7.*PI/4.,8.*PI/3),Interval(-PI/2,PI/2.),Interval(7.*PI/4.,5.*PI/2.),Interval(-PI/4,PI/2.)); x = Interval(-oo,oo); bwd_floor(Interval::empty(),x); CHECK(x == Interval::empty()); x = Interval(-oo,-0.000001); bwd_floor(Interval(-oo,-1),x); CHECK(x == Interval(-oo,-0.000001)); diff --git a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp index 4ba9ad3d..8799c599 100644 --- a/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp +++ b/tests/core/functions/analytic/codac2_tests_AnalyticFunction.cpp @@ -148,47 +148,47 @@ TEST_CASE("AnalyticFunction") //.def(py::self + py::self); CHECK(Approx(AnalyticFunction({x1}, cos(x1)+cos(x1)).eval(m, Interval(0.))) == Interval(2.)); //.def("__add__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)+x1).eval(m, pi)) == pi-1); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)+x1).eval(m, PI)) == PI-1); //.def("__radd__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, x1+cos(x1)).eval(m, pi)) == pi-1); + CHECK(Approx(AnalyticFunction({x1}, x1+cos(x1)).eval(m, PI)) == PI-1); //.def("__add__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)+Interval(10.)).eval(m, pi)) == Interval(9)); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)+Interval(10.)).eval(m, PI)) == Interval(9)); //.def("__radd__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, 10+cos(x1)).eval(m, pi)) == Interval(9)); + CHECK(Approx(AnalyticFunction({x1}, 10+cos(x1)).eval(m, PI)) == Interval(9)); //.def(- py::self); CHECK(Approx(AnalyticFunction({x1}, -cos(x1)).eval(m, Interval(0.))) == Interval(-1.)); //.def(py::self - py::self); CHECK(Approx(AnalyticFunction({x1}, cos(x1)-cos(x1)).eval(m, Interval(0.))) == Interval(0.)); //.def("__sub__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)-x1).eval(m, pi)) == -pi-1); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)-x1).eval(m, PI)) == -PI-1); //.def("__rsub__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, x1-cos(x1)).eval(m, pi)) == pi+1); + CHECK(Approx(AnalyticFunction({x1}, x1-cos(x1)).eval(m, PI)) == PI+1); //.def("__sub__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)-Interval(10.)).eval(m, pi)) == -Interval(11)); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)-Interval(10.)).eval(m, PI)) == -Interval(11)); //.def("__rsub__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, 10-cos(x1)).eval(m, pi)) == Interval(11)); + CHECK(Approx(AnalyticFunction({x1}, 10-cos(x1)).eval(m, PI)) == Interval(11)); //.def(py::self * py::self); CHECK(Approx(AnalyticFunction({x1}, cos(x1)*cos(x1)).eval(m, Interval(0.))) == Interval(1.)); //.def("__mul__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)*x1).eval(m, pi)) == -1*pi); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)*x1).eval(m, PI)) == -1*PI); //.def("__rmul__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, x1*cos(x1)).eval(m, pi)) == -1*pi); + CHECK(Approx(AnalyticFunction({x1}, x1*cos(x1)).eval(m, PI)) == -1*PI); //.def("__mul__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)*Interval(10.)).eval(m, pi),1e-9) == -Interval(10)); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)*Interval(10.)).eval(m, PI),1e-9) == -Interval(10)); //.def("__rmul__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, Interval(10.)*cos(x1)).eval(m, pi),1e-9) == -10); + CHECK(Approx(AnalyticFunction({x1}, Interval(10.)*cos(x1)).eval(m, PI),1e-9) == -10); //.def("__mul__", {}(const ScalarExpr& e1, const VectorExpr& e2); - CHECK(Approx(AnalyticFunction({v1,v2}, cos(v1[0])*(v2+v2)).eval(m, Vector({pi,-1}),Vector({2,3})),1e-9) == IntervalVector({-4,-6})); + CHECK(Approx(AnalyticFunction({v1,v2}, cos(v1[0])*(v2+v2)).eval(m, Vector({PI,-1}),Vector({2,3})),1e-9) == IntervalVector({-4,-6})); //.def("__truediv__", {}(const ScalarExpr& e1, const ScalarExpr& e2); CHECK(Approx(AnalyticFunction({x1}, cos(x1)/cos(x1)).eval(m, Interval(0.))) == Interval(1.)); //.def("__truediv__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)/x1).eval(m, pi)) == -1/pi); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)/x1).eval(m, PI)) == -1/PI); //.def("__rtruediv__", {}(const ScalarExpr& e1, const ScalarVar& e2); - CHECK(Approx(AnalyticFunction({x1}, x1/cos(x1)).eval(m, pi)) == -pi); + CHECK(Approx(AnalyticFunction({x1}, x1/cos(x1)).eval(m, PI)) == -PI); //.def("__truediv__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, cos(x1)/Interval(4.)).eval(m, pi)) == -1./4); + CHECK(Approx(AnalyticFunction({x1}, cos(x1)/Interval(4.)).eval(m, PI)) == -1./4); //.def("__rtruediv__", {}(const ScalarExpr& e1, const Interval& e2); - CHECK(Approx(AnalyticFunction({x1}, 4./cos(x1)).eval(m, pi)) == -4); + CHECK(Approx(AnalyticFunction({x1}, 4./cos(x1)).eval(m, PI)) == -4); // ======> VectorExpr @@ -218,7 +218,7 @@ TEST_CASE("AnalyticFunction") //.def("__rsub__", {}(const VectorExpr& e1, const IntervalVector& e2); CHECK(Approx(AnalyticFunction({v1,v2}, Vector({1,5})-(v1-v2)).eval(m, IntervalVector({2,3}),Vector({1,5}))) == IntervalVector({0,7})); //.def("__rmul__", {}(const VectorExpr& e1, const ScalarExpr& e2); - CHECK(Approx(AnalyticFunction({v1,v2}, cos(v1[0])*(v2+v2)).eval(m, Vector({pi,-1}),Vector({2,3})),1e-9) == IntervalVector({-4,-6})); + CHECK(Approx(AnalyticFunction({v1,v2}, cos(v1[0])*(v2+v2)).eval(m, Vector({PI,-1}),Vector({2,3})),1e-9) == IntervalVector({-4,-6})); //.def("__rmul__", {}(const VectorExpr& e1, const ScalarVar& e2); CHECK(Approx(AnalyticFunction({x1}, x1*vec(3*x1,2*x1)).eval(m, 3),1e-9) == IntervalVector({27,18})); } diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp index de92caf1..c538269d 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp @@ -67,13 +67,13 @@ TEST_CASE("SampledTrajectory as operator (1d case)") { ScalarVar t; AnalyticFunction f { {t}, cos(t) }; - AnalyticTrajectory analytic_traj(f, {-pi,pi}); + AnalyticTrajectory analytic_traj(f, {-PI,PI}); auto sampled_traj = analytic_traj.sampled(1e-2); auto g = sampled_traj.as_function(); AnalyticFunction h { {t}, g(t) }; - for(double t = -pi ; t < pi ; t+=1e-2) + for(double t = -PI ; t < PI ; t+=1e-2) CHECK(Approx(h.real_eval(t)) == cos(t)); } From f9f6f56350fc82dc807f055028df916a6b675ef2 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Fri, 27 Dec 2024 20:11:59 +0100 Subject: [PATCH 17/18] [pr] minor corrections --- tests/core/trajectory/codac2_tests_SampledTrajectory.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.py b/tests/core/trajectory/codac2_tests_SampledTrajectory.py index 7d3cdf91..b1d3128a 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.py +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.py @@ -96,7 +96,7 @@ def tests_SampledTrajectory(self): t_ = 0 while t_ < 5: - self.assertTrue(Approx(h.real_eval(t_)) == Vector([2*math.cos(t_),math.sin(2*t_)])) + self.assertTrue(Approx(h.real_eval(t_),1e-8) == Vector([2*math.cos(t_),math.sin(2*t_)])) t_=t_+1e-2 h = AnalyticFunction( @@ -106,7 +106,7 @@ def tests_SampledTrajectory(self): t_ = 0 while t_ < 5: - self.assertTrue(Approx(h.real_eval(t_)) == Vector([2*math.cos(t_),math.sin(2*t_)])) + self.assertTrue(Approx(h.real_eval(t_),1e-8) == Vector([2*math.cos(t_),math.sin(2*t_)])) t_=t_+1e-2 if __name__ == '__main__': From 60e0405b64cf960f4ee5054caf7079e50186bc75 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Fri, 27 Dec 2024 20:54:14 +0100 Subject: [PATCH 18/18] [pr] minor corrections --- tests/core/trajectory/codac2_tests_SampledTrajectory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp index c538269d..06207d17 100644 --- a/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp +++ b/tests/core/trajectory/codac2_tests_SampledTrajectory.cpp @@ -74,7 +74,7 @@ TEST_CASE("SampledTrajectory as operator (1d case)") AnalyticFunction h { {t}, g(t) }; for(double t = -PI ; t < PI ; t+=1e-2) - CHECK(Approx(h.real_eval(t)) == cos(t)); + CHECK(Approx(h.real_eval(t),1e-8) == cos(t)); } TEST_CASE("SampledTrajectory as operator (nd case)") @@ -96,7 +96,7 @@ TEST_CASE("SampledTrajectory as operator (nd case)") }; for(double t = 0 ; t < 5 ; t+=1e-2) - CHECK(Approx(h.real_eval(t)) == Vector({2*cos(t),sin(2*t)})); + CHECK(Approx(h.real_eval(t),1e-8) == Vector({2*cos(t),sin(2*t)})); } { AnalyticFunction h { @@ -105,6 +105,6 @@ TEST_CASE("SampledTrajectory as operator (nd case)") }; for(double t = 0 ; t < 5 ; t+=1e-2) - CHECK(Approx(h.real_eval(t)) == Vector({2*cos(t),sin(2*t)})); + CHECK(Approx(h.real_eval(t),1e-8) == Vector({2*cos(t),sin(2*t)})); } } \ No newline at end of file