diff --git a/python/src/core/domains/tube/codac_py_Tube.cpp b/python/src/core/domains/tube/codac_py_Tube.cpp index 9e2b0d6c..780ad74f 100644 --- a/python/src/core/domains/tube/codac_py_Tube.cpp +++ b/python/src/core/domains/tube/codac_py_Tube.cpp @@ -266,24 +266,24 @@ void export_Tube(py::module& m) // Setting values - .def("set", (void (Tube::*)(const Interval&))&Tube::set, - TUBE_VOID_SET_INTERVAL, + .def("set", (const Tube& (Tube::*)(const Interval&))&Tube::set, + TUBE_CONSTTUBE_SET_INTERVAL, "y"_a) - .def("set", (void (Tube::*)(const Interval&,int))&Tube::set, - TUBE_VOID_SET_INTERVAL_INT, + .def("set", (const Tube& (Tube::*)(const Interval&,int))&Tube::set, + TUBE_CONSTTUBE_SET_INTERVAL_INT, "y"_a, "slice_id"_a) - .def("set", (void (Tube::*)(const Interval&,double))&Tube::set, - TUBE_VOID_SET_INTERVAL_DOUBLE, + .def("set", (const Tube& (Tube::*)(const Interval&,double))&Tube::set, + TUBE_CONSTTUBE_SET_INTERVAL_DOUBLE, "y"_a, "t"_a) - .def("set", (void (Tube::*)(const Interval&,const Interval&))&Tube::set, - TUBE_VOID_SET_INTERVAL_INTERVAL, + .def("set", (const Tube& (Tube::*)(const Interval&,const Interval&))&Tube::set, + TUBE_CONSTTUBE_SET_INTERVAL_INTERVAL, "y"_a, "t"_a) .def("set_empty", &Tube::set_empty, - TUBE_VOID_SET_EMPTY) + TUBE_CONSTTUBE_SET_EMPTY) .def("inflate", (const Tube& (Tube::*)(double))&Tube::inflate, TUBE_CONSTTUBE_INFLATE_DOUBLE, diff --git a/python/src/core/domains/tube/codac_py_TubeVector.cpp b/python/src/core/domains/tube/codac_py_TubeVector.cpp index 573351f2..44f00017 100644 --- a/python/src/core/domains/tube/codac_py_TubeVector.cpp +++ b/python/src/core/domains/tube/codac_py_TubeVector.cpp @@ -261,40 +261,42 @@ void export_TubeVector(py::module& m) TUBEVECTOR_BOOL_OVERLAPS_TUBEVECTOR_FLOAT, "x"_a, "ratio"_a=1) + // todo: which functions to keep? (two implementations for each) + .def("set", [](TubeVector& x, const Vector& y) { x.set(y); }, - TUBEVECTOR_VOID_SET_INTERVALVECTOR, + TUBEVECTOR_CONSTTUBEVECTOR_SET_INTERVALVECTOR, "y"_a) .def("set", [](TubeVector& x, const Vector& y, int slice_id) { x.set(y, slice_id); }, - TUBEVECTOR_VOID_SET_INTERVALVECTOR_INT, + TUBEVECTOR_CONSTTUBEVECTOR_SET_INTERVALVECTOR_INT, "y"_a, "slice_id"_a) .def("set", [](TubeVector& x, const Vector& y, double t) { x.set(y, t); }, - TUBEVECTOR_VOID_SET_INTERVALVECTOR_DOUBLE, + TUBEVECTOR_CONSTTUBEVECTOR_SET_INTERVALVECTOR_DOUBLE, "y"_a, "t"_a) .def("set", [](TubeVector& x, const Vector& y, const Interval& t) { x.set(y, t); }, - TUBEVECTOR_VOID_SET_INTERVALVECTOR_INTERVAL, + TUBEVECTOR_CONSTTUBEVECTOR_SET_INTERVALVECTOR_INTERVAL, "y"_a, "t"_a) - .def("set", (void (TubeVector::*)(const IntervalVector&))&TubeVector::set, - TUBEVECTOR_VOID_SET_INTERVALVECTOR, + .def("set", (const TubeVector& (TubeVector::*)(const IntervalVector&))&TubeVector::set, + TUBEVECTOR_CONSTTUBEVECTOR_SET_INTERVALVECTOR, "y"_a) - .def("set", (void (TubeVector::*)(const IntervalVector&,int))&TubeVector::set, - TUBEVECTOR_VOID_SET_INTERVALVECTOR_INT, + .def("set", (const TubeVector& (TubeVector::*)(const IntervalVector&,int))&TubeVector::set, + TUBEVECTOR_CONSTTUBEVECTOR_SET_INTERVALVECTOR_INT, "y"_a, "slice_id"_a) - .def("set", (void (TubeVector::*)(const IntervalVector&,double))&TubeVector::set, - TUBEVECTOR_VOID_SET_INTERVALVECTOR_DOUBLE, + .def("set", (const TubeVector& (TubeVector::*)(const IntervalVector&,double))&TubeVector::set, + TUBEVECTOR_CONSTTUBEVECTOR_SET_INTERVALVECTOR_DOUBLE, "y"_a, "t"_a) - .def("set", (void (TubeVector::*)(const IntervalVector&,const Interval&))&TubeVector::set, - TUBEVECTOR_VOID_SET_INTERVALVECTOR_INTERVAL, + .def("set", (const TubeVector& (TubeVector::*)(const IntervalVector&,const Interval&))&TubeVector::set, + TUBEVECTOR_CONSTTUBEVECTOR_SET_INTERVALVECTOR_INTERVAL, "y"_a, "t"_a) .def("set_empty", &TubeVector::set_empty, - TUBEVECTOR_VOID_SET_EMPTY) + TUBEVECTOR_CONSTTUBEVECTOR_SET_EMPTY) .def("inflate", (const TubeVector& (TubeVector::*)(double))&TubeVector::inflate, TUBEVECTOR_CONSTTUBEVECTOR_INFLATE_DOUBLE, diff --git a/src/core/arithmetic/codac_tube_arithmetic_vector.cpp b/src/core/arithmetic/codac_tube_arithmetic_vector.cpp index 9528691c..235609e3 100644 --- a/src/core/arithmetic/codac_tube_arithmetic_vector.cpp +++ b/src/core/arithmetic/codac_tube_arithmetic_vector.cpp @@ -29,7 +29,7 @@ namespace codac return y; } - #define macro_vect_binary(f, feq) \ + #define macro_vect_binary(f) \ \ const TubeVector f(const TubeVector& x1, const TubeVector& x2) \ { \ @@ -85,10 +85,10 @@ namespace codac } \ \ - macro_vect_binary(operator+, operator+=); - macro_vect_binary(operator-, operator-=); - macro_vect_binary(operator|, operator|=); - macro_vect_binary(operator&, operator&=); + macro_vect_binary(operator+); + macro_vect_binary(operator-); + macro_vect_binary(operator|); + macro_vect_binary(operator&); const TubeVector operator*(const Interval& x1, const TubeVector& x2) { diff --git a/src/core/domains/tube/codac_Tube.cpp b/src/core/domains/tube/codac_Tube.cpp index bc4c0dbc..ac17c292 100644 --- a/src/core/domains/tube/codac_Tube.cpp +++ b/src/core/domains/tube/codac_Tube.cpp @@ -291,6 +291,38 @@ namespace codac return Polygon(v_pts); } + + const Trajectory Tube::lb() const + { + Trajectory lb; + + const Slice *s_x = first_slice(); + lb.set(s_x->input_gate().lb(), s_x->tdomain().lb()); + + while(s_x != NULL) + { + lb.set(s_x->output_gate().lb(), s_x->tdomain().ub()); + s_x = s_x->next_slice(); + } + + return lb; + } + + const Trajectory Tube::ub() const + { + Trajectory ub; + + const Slice *s_x = first_slice(); + ub.set(s_x->input_gate().ub(), s_x->tdomain().lb()); + + while(s_x != NULL) + { + ub.set(s_x->output_gate().ub(), s_x->tdomain().ub()); + s_x = s_x->next_slice(); + } + + return ub; + } // Slices structure @@ -1071,25 +1103,28 @@ namespace codac // Setting values - void Tube::set(const Interval& y) + const Tube& Tube::set(const Interval& y) { for(Slice *s = first_slice() ; s != NULL ; s = s->next_slice()) s->set(y); + return *this; } - void Tube::set(const Interval& y, int slice_id) + const Tube& Tube::set(const Interval& y, int slice_id) { assert(slice_id >= 0 && slice_id < nb_slices()); slice(slice_id)->set(y); + return *this; } - void Tube::set(const Interval& y, double t) + const Tube& Tube::set(const Interval& y, double t) { assert(tdomain().contains(t)); sample(t, y); + return *this; } - void Tube::set(const Interval& y, const Interval& t) + const Tube& Tube::set(const Interval& y, const Interval& t) { assert(tdomain().is_superset(t)); @@ -1106,11 +1141,13 @@ namespace codac s = s->next_slice()) s->set(y); } + + return *this; } - void Tube::set_empty() + const Tube& Tube::set_empty() { - set(Interval::EMPTY_SET); + return set(Interval::EMPTY_SET); } const Tube& Tube::inflate(double rad) diff --git a/src/core/domains/tube/codac_Tube.h b/src/core/domains/tube/codac_Tube.h index b2e76f12..ed30009c 100644 --- a/src/core/domains/tube/codac_Tube.h +++ b/src/core/domains/tube/codac_Tube.h @@ -202,6 +202,26 @@ namespace codac */ const Polygon polygon_envelope() const; + /** + * \brief Returns a possible lower bound \f$x^{-}(\cdot)\f$ of the tube + * + * \note The exact lower bound cannot be known. However, the returned trajectory \f$x^{-}(\cdot)\f$ + * is guaranteed to be enclosed in the tube \f$[x](\cdot)\f$. + * + * \return a candidate for \f$x^{-}(\cdot)\f$ + */ + const Trajectory lb() const; + + /** + * \brief Returns a possible upper bound \f$x^{+}(\cdot)\f$ of the tube + * + * \note The exact upper bound cannot be known. However, the returned trajectory \f$x^{+}(\cdot)\f$ + * is guaranteed to be enclosed in the tube \f$[x](\cdot)\f$. + * + * \return a candidate for \f$x^{+}(\cdot)\f$ + */ + const Trajectory ub() const; + /// @} /// \name Slices structure /// @{ @@ -710,16 +730,18 @@ namespace codac * \note The sampling of this tube is preserved * * \param y Interval value of the slices + * \return *this */ - void set(const Interval& y); + const Tube& set(const Interval& y); /** * \brief Sets the interval value of the ith slice of this tube * * \param y Interval value of the ith slice * \param slice_id index of the ith Slice + * \return *this */ - void set(const Interval& y, int slice_id); + const Tube& set(const Interval& y, int slice_id); /** * \brief Sets the interval value of this tube at \f$t\f$: \f$[x](t)=[y]\f$ @@ -730,8 +752,9 @@ namespace codac * * \param y Interval value of the gate * \param t the temporal key (double, must belong to the Tube's tdomain) + * \return *this */ - void set(const Interval& y, double t); + const Tube& set(const Interval& y, double t); /** * \brief Sets the interval value of this tube over \f$[t]\f$: \f$\forall t\in[t], [x](t)=[y]\f$ @@ -742,15 +765,17 @@ namespace codac * * \param y Interval value to be set * \param t the subtdomain (Interval, must be a subset of the Tube's tdomain) + * \return *this */ - void set(const Interval& y, const Interval& t); + const Tube& set(const Interval& y, const Interval& t); /** * \brief Sets this tube to the empty set * * \note By convention, all slices will be set to the empty set + * \return *this */ - void set_empty(); + const Tube& set_empty(); /** * \brief Inflates this tube by adding \f$[-rad,+rad]\f$ to all its codomain components diff --git a/src/core/domains/tube/codac_TubeVector.cpp b/src/core/domains/tube/codac_TubeVector.cpp index aa43e560..052d815c 100644 --- a/src/core/domains/tube/codac_TubeVector.cpp +++ b/src/core/domains/tube/codac_TubeVector.cpp @@ -257,6 +257,22 @@ namespace codac for(int i = 0 ; i < subvec.size() ; i++) (*this)[i + start_index] = subvec[i]; } + + const TrajectoryVector TubeVector::lb() const + { + TrajectoryVector lb(size()); + for(int i = 0 ; i < lb.size() ; i++) + lb[i] = (*this)[i].lb(); + return lb; + } + + const TrajectoryVector TubeVector::ub() const + { + TrajectoryVector ub(size()); + for(int i = 0 ; i < ub.size() ; i++) + ub[i] = (*this)[i].ub(); + return ub; + } // Slices structure @@ -715,41 +731,46 @@ namespace codac // Setting values - void TubeVector::set(const IntervalVector& y) + const TubeVector& TubeVector::set(const IntervalVector& y) { assert(size() == y.size()); for(int i = 0 ; i < size() ; i++) (*this)[i].set(y[i]); + return *this; } - void TubeVector::set(const IntervalVector& y, int slice_id) + const TubeVector& TubeVector::set(const IntervalVector& y, int slice_id) { assert(size() == y.size()); assert(slice_id >= 0 && slice_id < nb_slices()); for(int i = 0 ; i < size() ; i++) (*this)[i].set(y[i], slice_id); + return *this; } - void TubeVector::set(const IntervalVector& y, double t) + const TubeVector& TubeVector::set(const IntervalVector& y, double t) { assert(size() == y.size()); assert(tdomain().contains(t)); for(int i = 0 ; i < size() ; i++) (*this)[i].set(y[i], t); + return *this; } - void TubeVector::set(const IntervalVector& y, const Interval& t) + const TubeVector& TubeVector::set(const IntervalVector& y, const Interval& t) { assert(size() == y.size()); assert(tdomain().is_superset(t)); for(int i = 0 ; i < size() ; i++) (*this)[i].set(y[i], t); + return *this; } - void TubeVector::set_empty() + const TubeVector& TubeVector::set_empty() { for(int i = 0 ; i < size() ; i++) (*this)[i].set_empty(); + return *this; } const TubeVector& TubeVector::inflate(double rad) diff --git a/src/core/domains/tube/codac_TubeVector.h b/src/core/domains/tube/codac_TubeVector.h index e2a88051..d32aa270 100644 --- a/src/core/domains/tube/codac_TubeVector.h +++ b/src/core/domains/tube/codac_TubeVector.h @@ -250,6 +250,26 @@ namespace codac */ const Interval tdomain() const; + /** + * \brief Returns a possible lower bound \f$\mathbf{x}^{-}(\cdot)\f$ of the tube + * + * \note The exact lower bound cannot be known. However, the returned trajectory \f$\mathbf{x}^{-}(\cdot)\f$ + * is guaranteed to be enclosed in the tube \f$[\mathbf{x}](\cdot)\f$. + * + * \return a candidate for \f$\mathbf{x}^{-}(\cdot)\f$ + */ + const TrajectoryVector lb() const; + + /** + * \brief Returns a possible upper bound \f$\mathbf{x}^{+}(\cdot)\f$ of the tube + * + * \note The exact upper bound cannot be known. However, the returned trajectory \f$\mathbf{x}^{+}(\cdot)\f$ + * is guaranteed to be enclosed in the tube \f$[\mathbf{x}](\cdot)\f$. + * + * \return a candidate for \f$\mathbf{x}^{+}(\cdot)\f$ + */ + const TrajectoryVector ub() const; + /// @} /// \name Slices structure /// @{ @@ -648,16 +668,18 @@ namespace codac * \note The sampling of this tube is preserved * * \param y IntervalVector value of the slices + * \return *this */ - void set(const IntervalVector& y); + const TubeVector& set(const IntervalVector& y); /** * \brief Sets the box value of the ith slice of this tube * * \param y IntervalVector value of the ith slice * \param slice_id index of the ith Slice + * \return *this */ - void set(const IntervalVector& y, int slice_id); + const TubeVector& set(const IntervalVector& y, int slice_id); /** * \brief Sets the box value of this tube at \f$t\f$: \f$[\mathbf{x}](t)=[\mathbf{y}]\f$ @@ -668,8 +690,9 @@ namespace codac * * \param y IntervalVector value of the gate * \param t the temporal key (double, must belong to the TubeVector's tdomain) + * \return *this */ - void set(const IntervalVector& y, double t); + const TubeVector& set(const IntervalVector& y, double t); /** * \brief Sets the box value of this tube over \f$[t]\f$: \f$\forall t\in[t], [\mathbf{x}](t)=[\mathbf{y}]\f$ @@ -680,15 +703,17 @@ namespace codac * * \param y IntervalVector value to be set * \param t the subtdomain (Interval, must be a subset of the TubeVector's tdomain) + * \return *this */ - void set(const IntervalVector& y, const Interval& t); + const TubeVector& set(const IntervalVector& y, const Interval& t); /** * \brief Sets this tube to the empty set * * \note By convention, all slices will be set to the empty set + * \return *this */ - void set_empty(); + const TubeVector& set_empty(); /** * \brief Inflates this tube by adding \f$[-\mathbf{rad},+\mathbf{rad}]\f$ to all its codomain components