diff --git a/doc/manual/development/changelog.rst b/doc/manual/development/changelog.rst index dc12a2076..1002ecf90 100644 --- a/doc/manual/development/changelog.rst +++ b/doc/manual/development/changelog.rst @@ -3,6 +3,14 @@ Changelog ========= +Upcoming version +**************** + +Pull Request #379 from godardma (27/04) +--------------------------------------- + +``Zonotope`` and ``Parallelepiped`` center is now ``c`` instead of ``z`` to avoid ambiguity. + Version 2.0.2 ************* diff --git a/doc/manual/manual/geometry/zonotope.png b/doc/manual/manual/geometry/zonotope.png index fb74b6718..cc0584583 100644 Binary files a/doc/manual/manual/geometry/zonotope.png and b/doc/manual/manual/geometry/zonotope.png differ diff --git a/doc/manual/manual/geometry/zonotope.rst b/doc/manual/manual/geometry/zonotope.rst index 2fe1f1354..a0471be64 100644 --- a/doc/manual/manual/geometry/zonotope.rst +++ b/doc/manual/manual/geometry/zonotope.rst @@ -16,13 +16,13 @@ A zonotope is a convex and symmetric polytope. It can be represented as the Minkowski sum of a finite number of line segments, which are called its generators. In Codac, zonotopes are represented by the class :class:`Zonotope`. A zonotope is defined by its center and its generators. -The center is a :class:`Vector`, noted :math:`z`, and the generators are stored in a :class:`Matrix`, noted :math:`A`. +The center is a :class:`Vector`, noted :math:`\mathbf{c}`, and the generators are stored in a :class:`Matrix`, noted :math:`\mathbf{A}`. Each column of the matrix corresponds to a generator. The resulting zonotope is: .. math:: - Z = z + A \cdot [-1,1]^m + Z = \mathbf{c} + \mathbf{A} \cdot [-1,1]^m Where :math:`m` is the number of generators (i.e., the number of columns of the matrix :math:`A`). @@ -37,24 +37,24 @@ It can be constructed in Codac as follows: .. code-tab:: py - z = Vector([1,2]) + c = Vector([1,2]) A = Matrix([[1,0,2],[0,1,1]]) - Z = Zonotope(z, A) + Z = Zonotope(c, A) .. code-tab:: c++ - Vector z({1,2}); + Vector c({1,2}); Matrix A({{1,0,2},{0,1,1}}); - Zonotope Z(z, A); + Zonotope Z(c, A); .. code-tab:: matlab - z = Vector({1,2}); + c = Vector({1,2}); A = Matrix({{1,0,2},{0,1,1}}); - Z = Zonotope(z,A); + Z = Zonotope(c,A); The resulting zonotope is represented in the figure below: diff --git a/python/src/core/domains/zonotope/codac2_py_Zonotope.cpp b/python/src/core/domains/zonotope/codac2_py_Zonotope.cpp index 7b0977919..ab4e578f1 100644 --- a/python/src/core/domains/zonotope/codac2_py_Zonotope.cpp +++ b/python/src/core/domains/zonotope/codac2_py_Zonotope.cpp @@ -39,8 +39,12 @@ void export_Zonotope(py::module& m) ZONOTOPE_ZONOTOPE_PROJ_CONST_VECTOR_INDEX_REF_CONST, "indices"_a) - .def_readwrite("z", &Zonotope::z, - VECTOR_ZONOTOPE_Z) + .def("__add__", &Zonotope::operator+, + ZONOTOPE_ZONOTOPE_OPERATORPLUS_CONST_ZONOTOPE_REF, + py::is_operator()) + + .def_readwrite("c", &Zonotope::c, + VECTOR_ZONOTOPE_C) .def_readwrite("A", &Zonotope::A, MATRIX_ZONOTOPE_A) diff --git a/python/src/graphics/figures/codac2_py_Figure3D.cpp b/python/src/graphics/figures/codac2_py_Figure3D.cpp index 24dbf165f..58068aba5 100644 --- a/python/src/graphics/figures/codac2_py_Figure3D.cpp +++ b/python/src/graphics/figures/codac2_py_Figure3D.cpp @@ -35,8 +35,8 @@ void export_Figure3D(py::module& m) CONST_STRING_REF_FIGURE3D_NAME_CONST) .def("draw_axes", &Figure3D::draw_axes, - VOID_FIGURE3D_DRAW_AXES_DOUBLE, - "size"_a=1.0) + VOID_FIGURE3D_DRAW_AXES_DOUBLE_CONST_VECTOR_REF, + "size"_a=1.0, "origin"_a=py::none()) // Geometric shapes .def("draw_triangle", (void(Figure3D::*)(const Vector &c, const Matrix &A, const Vector &p1, const Vector &p2, const Vector &p3, const StyleProperties &s))&Figure3D::draw_triangle, diff --git a/src/core/domains/zonotope/codac2_Parallelepiped.cpp b/src/core/domains/zonotope/codac2_Parallelepiped.cpp index ef75b58fa..280ff0896 100644 --- a/src/core/domains/zonotope/codac2_Parallelepiped.cpp +++ b/src/core/domains/zonotope/codac2_Parallelepiped.cpp @@ -12,29 +12,29 @@ using namespace codac2; -Parallelepiped::Parallelepiped(const Vector& z_, const Matrix& A_) - : Zonotope(z_, A_) +Parallelepiped::Parallelepiped(const Vector& c_, const Matrix& A_) + : Zonotope(c_, A_) { - assert_release(A.cols() <= z.size() && "too many vectors, you are describing a zonotope"); + assert_release(A.cols() <= c.size() && "too many vectors, you are describing a zonotope"); } -void generate_vertices(Index i, Index n, const Vector& z, const Matrix& A, std::vector& L_v) +void generate_vertices(Index i, Index n, const Vector& c, const Matrix& A, std::vector& L_v) { if (i == n) { - L_v.push_back(z); + L_v.push_back(c); } else if (i Parallelepiped::vertices() const { std::vector L_v; - generate_vertices(0, z.size(),z,A,L_v); + generate_vertices(0, c.size(),c,A,L_v); return L_v; } @@ -46,9 +46,9 @@ BoolInterval Parallelepiped::contains(const Vector& v) const BoolInterval Parallelepiped::is_superset(const IntervalVector& x) const { assert_release(A.rows() == A.cols() && "Matrix A must be square to check containment."); - assert_release(x.size() == z.size() && "Point dimension must match parallelepiped dimension."); + assert_release(x.size() == c.size() && "Point dimension must match parallelepiped dimension."); - IntervalVector B = inverse_enclosure(A)*(x - z); + IntervalVector B = inverse_enclosure(A)*(x - c); IntervalVector IV = IntervalVector::constant(A.cols(),{-1,1}); if (!(B.intersects(IV))) diff --git a/src/core/domains/zonotope/codac2_Parallelepiped.h b/src/core/domains/zonotope/codac2_Parallelepiped.h index 19b6d9338..20e17bff1 100644 --- a/src/core/domains/zonotope/codac2_Parallelepiped.h +++ b/src/core/domains/zonotope/codac2_Parallelepiped.h @@ -21,9 +21,9 @@ namespace codac2 /** * \class Parallelepiped * - * \brief Class representing a parallelepiped \f$\mathbf{z} + \mathbf{A}\cdot[-1,1]^m\f$ + * \brief Class representing a parallelepiped \f$\mathbf{c} + \mathbf{A}\cdot[-1,1]^m\f$ * - * This class represents a parallelepiped in n-dimensional space, defined by a center point \f$\mathbf{z}\f$ and a shape matrix \f$\mathbf{A}\f$. + * This class represents a parallelepiped in n-dimensional space, defined by a center point \f$\mathbf{c}\f$ and a shape matrix \f$\mathbf{A}\f$. * * A parallelepiped is a special case of a zonotope where the shape matrix \f$\mathbf{A}\f$ has \f$m\f$ columns with \f$m \leqslant n\f$. */ @@ -34,10 +34,10 @@ namespace codac2 /** * \brief Constructs a n-parallelepiped object with a given center and shape matrix * - * \param z Center of the parallelepiped (n-dimensional vector) + * \param c Center of the parallelepiped (n-dimensional vector) * \param A Shape matrix of the parallelepiped (\f$n\times m\f$ matrix with \f$m \leqslant n\f$) */ - Parallelepiped(const Vector& z, const Matrix& A); + Parallelepiped(const Vector& c, const Matrix& A); /** * \brief Computes the vertices of the parallelepiped diff --git a/src/core/domains/zonotope/codac2_Zonotope.cpp b/src/core/domains/zonotope/codac2_Zonotope.cpp index 9091e7f4d..8eb9dabe8 100644 --- a/src/core/domains/zonotope/codac2_Zonotope.cpp +++ b/src/core/domains/zonotope/codac2_Zonotope.cpp @@ -11,31 +11,42 @@ using namespace codac2; -Zonotope::Zonotope(const Vector& z_, const Matrix& A_) - : z(z_), A(A_) +Zonotope::Zonotope(const Vector& c_, const Matrix& A_) + : c(c_), A(A_) { - assert_release(z.size() == A.rows()); + assert_release(c.size() == A.rows()); } IntervalVector Zonotope::box() const { - return z + (A.template cast())*IntervalVector::constant(A.cols(),{-1,1}); + return c + (A.template cast())*IntervalVector::constant(A.cols(),{-1,1}); } Zonotope Zonotope::proj(const std::vector& indices) const { assert_release(*std::min_element(indices.begin(), indices.end()) >= 0 && "indices out of range"); - assert_release(*std::max_element(indices.begin(), indices.end()) <= z.size() && "indices out of range"); + assert_release(*std::max_element(indices.begin(), indices.end()) <= c.size() && "indices out of range"); Matrix A_cropped (indices.size(), A.cols()); - Vector z_cropped (indices.size()); + Vector c_cropped (indices.size()); for (size_t i = 0; i < indices.size(); ++i) { A_cropped.row(i) = A.row(indices[i]); - z_cropped[i] = z[indices[i]]; + c_cropped[i] = c[indices[i]]; } - return Zonotope(z_cropped, A_cropped); + return Zonotope(c_cropped, A_cropped); } +Zonotope Zonotope::operator+(const Zonotope& zonotope) +{ + assert_release(c.size() == zonotope.c.size() && "Zonotopes must have the same dimension"); + + Vector c_sum = c + zonotope.c; + Matrix A_sum (A.rows(), A.cols() + zonotope.A.cols()); + + A_sum << A, zonotope.A; + + return Zonotope(c_sum, A_sum); +} diff --git a/src/core/domains/zonotope/codac2_Zonotope.h b/src/core/domains/zonotope/codac2_Zonotope.h index 863a2681b..ad1255b61 100644 --- a/src/core/domains/zonotope/codac2_Zonotope.h +++ b/src/core/domains/zonotope/codac2_Zonotope.h @@ -18,11 +18,11 @@ namespace codac2 { /** * \class Zonotope - * \brief Class representing a zonotope \f$\mathbf{z} + \mathbf{A}\cdot[-1,1]^m\f$ + * \brief Class representing a zonotope \f$\mathbf{c} + \mathbf{A}\cdot[-1,1]^m\f$ * - * This class represents a zonotope in n-dimensional space, defined by a center point \f$\mathbf{z}\f$ and a shape matrix \f$\mathbf{A}\f$. + * This class represents a zonotope in n-dimensional space, defined by a center point \f$\mathbf{c}\f$ and a shape matrix \f$\mathbf{A}\f$. * - * The vector \f$\mathbf{z}\f$ and each column of the matrix \f$\mathbf{A}\f$ must have the same dimension \f$n\f$, but the matrix \f$\mathbf{A}\f$ can have any number of columns \f$m\f$. + * The vector \f$\mathbf{c}\f$ and each column of the matrix \f$\mathbf{A}\f$ must have the same dimension \f$n\f$, but the matrix \f$\mathbf{A}\f$ can have any number of columns \f$m\f$. */ class Zonotope { @@ -31,10 +31,10 @@ namespace codac2 /** * \brief Constructs a n-zonotope object with a given center and shape matrix * - * \param z Center of the zonotope (n-dimensional vector) + * \param c Center of the zonotope (n-dimensional vector) * \param A Shape matrix of the zonotope (\f$n\times m\f$ matrix) */ - Zonotope(const Vector& z, const Matrix& A); + Zonotope(const Vector& c, const Matrix& A); /** * \brief Computes the axis-aligned bounding box of the zonotope @@ -52,10 +52,19 @@ namespace codac2 */ Zonotope proj(const std::vector& indices) const; + /** + * \brief Computes the Minkowski sum of this Zonotope with another Zonotope + * + * \param zonotope The other Zonotope to add to this one + * + * \return A new Zonotope object representing the Minkowski sum of the two Zonotopes + */ + Zonotope operator+(const Zonotope& zonotope); + /** * \brief Center of the zonotope */ - Vector z; + Vector c; /** * \brief Shape matrix of the zonotope diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index 337a64d03..0fe6fd645 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -220,17 +220,17 @@ namespace codac2 "Parallelepiped evaluation requires at least one input."); IntervalVector Y = this->eval(((typename Wrapper::Domain)(x)).mid()...); - Vector z = Y.mid(); + Vector c = Y.mid(); Matrix A = this->diff(((typename Wrapper::Domain)(x)).mid()...).mid(); // Maximum error computation - double rho = error_peibos(Y, z, this->diff(x...), A, cart_prod(x...)); + double rho = error_peibos(Y, c, this->diff(x...), A, cart_prod(x...)); // Inflation of the parallelepiped Matrix A_inf = inflate_flat_parallelepiped(A, (cart_prod(x...).template cast()).rad(), rho); - return Parallelepiped(z, A_inf); + return Parallelepiped(c, A_inf); } Index output_size() const diff --git a/src/graphics/figures/codac2_Figure2D.cpp b/src/graphics/figures/codac2_Figure2D.cpp index 53045ebc1..33cbb962b 100644 --- a/src/graphics/figures/codac2_Figure2D.cpp +++ b/src/graphics/figures/codac2_Figure2D.cpp @@ -255,7 +255,7 @@ void Figure2D::draw_zonotope(const Zonotope& z, const StyleProperties& style) } } vector vertices; - Vector point=z.z; + Vector point=z.c; // Start from v[1] maximum (and v[0] min for horizontal side) for (const auto& a : sides) { point+=a.second; @@ -277,17 +277,17 @@ void Figure2D::draw_zonotope(const Zonotope& z, const StyleProperties& style) void Figure2D::draw_parallelepiped(const Parallelepiped& p, const StyleProperties& style) { - assert_release(p.A.is_squared() && p.A.rows() == p.z.size()); - assert_release(p.z.size() == 2); + assert_release(p.A.is_squared() && p.A.rows() == p.c.size()); + assert_release(p.c.size() == 2); auto a1 = p.A.col(0), a2 = p.A.col(1); if (a1.isZero() || a2.isZero()) - draw_polyline({p.z-a1-a2,p.z+a1+a2}, style); + draw_polyline({p.c-a1-a2,p.c+a1+a2}, style); else draw_polygon({ - p.z+a1+a2, p.z-a1+a2, - p.z-a1-a2, p.z+a1-a2 + p.c+a1+a2, p.c-a1+a2, + p.c-a1-a2, p.c+a1-a2 }, style); } diff --git a/src/graphics/figures/codac2_Figure2D.h b/src/graphics/figures/codac2_Figure2D.h index 9a950ea18..3b920c734 100644 --- a/src/graphics/figures/codac2_Figure2D.h +++ b/src/graphics/figures/codac2_Figure2D.h @@ -310,7 +310,7 @@ namespace codac2 void draw_parallelepiped(const Parallelepiped& p, const StyleProperties& style = StyleProperties()); /** - * \brief Draws a zonotope z+sum_i [-1,1] A_i on the figure + * \brief Draws a zonotope c+sum_i [-1,1] A_i on the figure * * \param z Zonotope to draw (center and shape matrix) * \param style Style of the zonotope (edge color and fill color) @@ -856,15 +856,15 @@ namespace codac2 } /** - * \brief Draws a zonotope z+sum_i [-1,1] A_i on the figure + * \brief Draws a zonotope c+sum_i [-1,1] A_i on the figure * - * \param z Zonotope to draw (center and shape matrix) + * \param c Zonotope to draw (center and shape matrix) * \param style Style of the zonotope (edge color and fill color) */ - static void draw_zonotope(const Zonotope& z, const StyleProperties& style = StyleProperties()) + static void draw_zonotope(const Zonotope& c, const StyleProperties& style = StyleProperties()) { auto_init(); - selected_fig()->draw_zonotope(z,style); + selected_fig()->draw_zonotope(c,style); } /** diff --git a/src/graphics/figures/codac2_Figure3D.cpp b/src/graphics/figures/codac2_Figure3D.cpp index 86d7fcdc0..ca0aee3ef 100644 --- a/src/graphics/figures/codac2_Figure3D.cpp +++ b/src/graphics/figures/codac2_Figure3D.cpp @@ -105,19 +105,19 @@ void Figure3D::draw_parallelogram(const Vector &c, const Matrix &A, void Figure3D::draw_parallelepiped(const Parallelepiped& p, const StyleProperties& style) { - assert_release(p.z.size() == 3); + assert_release(p.c.size() == 3); assert_release(p.A.rows() == 3 && p.A.cols() == 3); this->set_style_internal(style); - size_t ip0 = this->move_write_v(p.z,p.A,Vector({-1,-1,-1})); - size_t ip1 = this->move_write_v(p.z,p.A,Vector({-1,-1,1})); - size_t ip2 = this->move_write_v(p.z,p.A,Vector({-1,1,-1})); - size_t ip3 = this->move_write_v(p.z,p.A,Vector({-1,1,1})); - size_t ip4 = this->move_write_v(p.z,p.A,Vector({1,-1,-1})); - size_t ip5 = this->move_write_v(p.z,p.A,Vector({1,-1,1})); - size_t ip6 = this->move_write_v(p.z,p.A,Vector({1,1,-1})); - size_t ip7 = this->move_write_v(p.z,p.A,Vector({1,1,1})); + size_t ip0 = this->move_write_v(p.c,p.A,Vector({-1,-1,-1})); + size_t ip1 = this->move_write_v(p.c,p.A,Vector({-1,-1,1})); + size_t ip2 = this->move_write_v(p.c,p.A,Vector({-1,1,-1})); + size_t ip3 = this->move_write_v(p.c,p.A,Vector({-1,1,1})); + size_t ip4 = this->move_write_v(p.c,p.A,Vector({1,-1,-1})); + size_t ip5 = this->move_write_v(p.c,p.A,Vector({1,-1,1})); + size_t ip6 = this->move_write_v(p.c,p.A,Vector({1,1,-1})); + size_t ip7 = this->move_write_v(p.c,p.A,Vector({1,1,1})); _file << "f " << ip0 << " " << ip1 << " " << ip3 << " " << ip2 << "\n"; _file << "f " << ip4 << " " << ip5 << " " << ip7 << " " << ip6 << "\n"; @@ -137,7 +137,7 @@ void Figure3D::draw_box(const IntervalVector& x, const StyleProperties& style) } void Figure3D::draw_zonotope(const Zonotope& z, const StyleProperties& style) { - assert_release(z.z.size() == 3); + assert_release(z.c.size() == 3); Matrix id = Matrix::Identity(3,3); this->set_style_internal(style); lock_style=true; @@ -186,8 +186,8 @@ void Figure3D::draw_zonotope(const Zonotope& z, const StyleProperties& style) { R1 -= Ak; } } - this->draw_parallelogram(z.z,id,R1+R2,Ai,Aj,style); - this->draw_parallelogram(z.z,id,-R1+R2,Ai,Aj,style); + this->draw_parallelogram(z.c,id,R1+R2,Ai,Aj,style); + this->draw_parallelogram(z.c,id,-R1+R2,Ai,Aj,style); } } lock_style=false; @@ -214,10 +214,11 @@ void Figure3D::draw_arrow(const Vector& c, const Matrix &A, } -void Figure3D::draw_axes(double size) +void Figure3D::draw_axes(double size, const Vector& origin) { + assert_release(origin.size()==3); const std::string name="axes"; - Vector z = Vector::zero(3); + Vector z = origin; // X axis Matrix AX = Matrix::Identity(3,3); draw_arrow(z,size*AX,StyleProperties(Color::red(),name)); diff --git a/src/graphics/figures/codac2_Figure3D.h b/src/graphics/figures/codac2_Figure3D.h index 3887bdee1..442293832 100644 --- a/src/graphics/figures/codac2_Figure3D.h +++ b/src/graphics/figures/codac2_Figure3D.h @@ -116,7 +116,7 @@ namespace codac2 void draw_parallelepiped(const Parallelepiped& p, const StyleProperties& style = { Color::dark_gray(0.5) }); /** - * \brief Draws a zonotope z+sum_i [-1,1] A_i on the figure + * \brief Draws a zonotope c+sum_i [-1,1] A_i on the figure * * \param z Zonotope to draw (center and shape matrix) * \param style Style of the zonotope (edge color) @@ -146,8 +146,9 @@ namespace codac2 * \brief Draws the (x,y,z) axes on the figure in red, green and blue * * \param size Size of the axes + * \param origin Origin of the axes */ - void draw_axes(double size = 1.0); + void draw_axes(double size = 1.0, const Vector& origin = Vector::Zero(3)); /** * \brief Draws a parametric surface diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c38934659..4ea53368d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -54,8 +54,9 @@ list(APPEND SRC_TESTS # listing files without extension core/domains/interval/codac2_tests_IntervalMatrix core/domains/interval/codac2_tests_IntervalVector ../doc/manual/manual/intervals/src - core/domains/zonotope/codac2_tests_Parallelepiped core/domains/zonotope/codac2_tests_Parallelepiped_eval + core/domains/zonotope/codac2_tests_Parallelepiped + core/domains/zonotope/codac2_tests_Zonotope core/domains/tube/codac2_tests_TDomain core/domains/tube/codac2_tests_Slice core/domains/tube/codac2_tests_Slice_polygon diff --git a/tests/core/domains/zonotope/codac2_tests_Parallelepiped.cpp b/tests/core/domains/zonotope/codac2_tests_Parallelepiped.cpp index 2c5766d4b..2d203740b 100644 --- a/tests/core/domains/zonotope/codac2_tests_Parallelepiped.cpp +++ b/tests/core/domains/zonotope/codac2_tests_Parallelepiped.cpp @@ -26,7 +26,7 @@ TEST_CASE("Parallelepiped") CHECK((p.is_superset(IntervalVector({{0.,5.},{2.,7.},{4.,9.}})))==BoolInterval::UNKNOWN); Zonotope z = p.proj({2,1,0}); - CHECK(z.z == Vector({4,2,0})); + CHECK(z.c == Vector({4,2,0})); CHECK(z.A == Matrix({{0.,1.,1.},{0.,1.,0.},{0.5,0.,0.}})); CHECK(z.box() == IntervalVector({{2.,6.},{1.,3.},{-0.5,0.5}})); } diff --git a/tests/core/domains/zonotope/codac2_tests_Parallelepiped.py b/tests/core/domains/zonotope/codac2_tests_Parallelepiped.py index 75b4cd987..c0eaa0a17 100644 --- a/tests/core/domains/zonotope/codac2_tests_Parallelepiped.py +++ b/tests/core/domains/zonotope/codac2_tests_Parallelepiped.py @@ -27,7 +27,7 @@ def test_parallelepiped(self): self.assertTrue((p.is_superset(IntervalVector([[0.,5.],[2.,7.],[4.,9.]])))==BoolInterval.UNKNOWN) z = p.proj([2,1,0]) - self.assertTrue(z.z == Vector([4,2,0])) + self.assertTrue(z.c == Vector([4,2,0])) self.assertTrue(z.A == Matrix([[0,1,1],[0,1,0],[0.5,0,0]])) self.assertTrue(z.box() == IntervalVector([[2,6],[1,3],[-0.5,0.5]])) diff --git a/tests/core/domains/zonotope/codac2_tests_Parallelepiped_eval.cpp b/tests/core/domains/zonotope/codac2_tests_Parallelepiped_eval.cpp index 0ad038b38..9dd1705b2 100644 --- a/tests/core/domains/zonotope/codac2_tests_Parallelepiped_eval.cpp +++ b/tests/core/domains/zonotope/codac2_tests_Parallelepiped_eval.cpp @@ -28,17 +28,17 @@ TEST_CASE("Parallelepiped_eval") auto p1a = f1.parallelepiped_eval(Interval(-0.1,0.1)); auto p1b = f1.parallelepiped_eval(1.0); - CHECK(Approx(p1a.z,1e-6) == Vector({0,0})); + CHECK(Approx(p1a.c,1e-6) == Vector({0,0})); CHECK(Approx(p1a.A,1e-6) == Matrix({{0.12,0},{0,0.02}})); - CHECK(Approx(p1b.z,1e-6) == Vector({1,1})); + CHECK(Approx(p1b.c,1e-6) == Vector({1,1})); CHECK(Approx(p1b.A,1e-6) == Matrix({{0,0},{0,0}})); auto pa = f2.parallelepiped_eval(Interval(-0.1,0.1), Interval(-0.1,0.1)); auto pb = f2.parallelepiped_eval(1.0, Interval(-1,1)); - CHECK(Approx(pa.z,1e-6) == Vector({0,0,0})); + CHECK(Approx(pa.c,1e-6) == Vector({0,0,0})); CHECK(Approx(pa.A,1e-6) == Matrix({{0.14,0,0},{0,0.14,0},{0,0,0.04}})); - CHECK(Approx(pb.z,1e-6) == Vector({1,0,1})); + CHECK(Approx(pb.c,1e-6) == Vector({1,0,1})); CHECK(Approx(pb.A,1e-5) == Matrix({{0.894428,0,1.78886},{0,3,0},{1.78886,0,-0.894427}})); @@ -55,7 +55,7 @@ TEST_CASE("Parallelepiped_eval") auto p2 = f2.parallelepiped_eval(X0,Y0); auto p3 = f3.parallelepiped_eval(IntervalVector({X0,Y0})); - CHECK(Approx(p2.z,1e-6) == p3.z); + CHECK(Approx(p2.c,1e-6) == p3.c); CHECK(Approx(p2.A,1e-6) == p3.A); y0+=dx; } diff --git a/tests/core/domains/zonotope/codac2_tests_Parallelepiped_eval.py b/tests/core/domains/zonotope/codac2_tests_Parallelepiped_eval.py index c7dcd18ed..5cac5ffe7 100644 --- a/tests/core/domains/zonotope/codac2_tests_Parallelepiped_eval.py +++ b/tests/core/domains/zonotope/codac2_tests_Parallelepiped_eval.py @@ -27,17 +27,17 @@ def test_parallelepiped_eval(self): p1a = f1.parallelepiped_eval(Interval(-0.1,0.1)) p1b = f1.parallelepiped_eval(1.0) - self.assertTrue(Approx(p1a.z,1e-6)==Vector([0.0,0.0])) + self.assertTrue(Approx(p1a.c,1e-6)==Vector([0.0,0.0])) self.assertTrue(Approx(p1a.A,1e-6)==Matrix([[0.12,0.0],[0.0,0.02]])) - self.assertTrue(Approx(p1b.z,1e-6)==Vector([1.0,1.0])) + self.assertTrue(Approx(p1b.c,1e-6)==Vector([1.0,1.0])) self.assertTrue(Approx(p1b.A,1e-6)==Matrix([[0.0,0.0],[0.0,0.0]])) pa = f2.parallelepiped_eval(Interval(-0.1,0.1), Interval(-0.1,0.1)) pb = f2.parallelepiped_eval(1.0,Interval(-1,1)) - self.assertTrue(Approx(pa.z,1e-6)==Vector([0,0,0])) + self.assertTrue(Approx(pa.c,1e-6)==Vector([0,0,0])) self.assertTrue(Approx(pa.A,1e-6)==Matrix([[0.14,0,0],[0,0.14,0],[0,0,0.04]])) - self.assertTrue(Approx(pb.z,1e-6)==Vector([1,0,1])) + self.assertTrue(Approx(pb.c,1e-6)==Vector([1,0,1])) self.assertTrue(Approx(pb.A,1e-5)==Matrix([[0.894428,0,1.78886],[0,3,0],[1.78886,0,-0.894427]])) @@ -52,7 +52,7 @@ def test_parallelepiped_eval(self): p2 = f2.parallelepiped_eval(X0,Y0) p3 = f3.parallelepiped_eval(IntervalVector([X0,Y0])) - self.assertTrue(Approx(p2.z,1e-6)==p3.z) + self.assertTrue(Approx(p2.c,1e-6)==p3.c) self.assertTrue(Approx(p2.A,1e-6)==p3.A) y0 += dx x0 += dx diff --git a/tests/core/domains/zonotope/codac2_tests_Zonotope.cpp b/tests/core/domains/zonotope/codac2_tests_Zonotope.cpp new file mode 100644 index 000000000..60da5d7ea --- /dev/null +++ b/tests/core/domains/zonotope/codac2_tests_Zonotope.cpp @@ -0,0 +1,28 @@ +/** + * Codac tests + * ---------------------------------------------------------------------------- + * \date 2025 + * \author Maël Godard + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#include +#include + +using namespace std; +using namespace codac2; + +TEST_CASE("Zonotope") +{ + Zonotope Z1 (Vector({2,1}), Matrix({{0.2 ,0.08}, {0.04,0.18}})); + Zonotope Z2 (Vector({2,0.5}), Matrix({{-0.2}, {0.1}})); + auto Zs = Z1+Z2; + + Vector c ({4,1.5}); + Matrix A ({{0.2, 0.08, -0.2}, + {0.04, 0.18, 0.1}}); + CHECK(Zs.c == c); + CHECK(Zs.A == A); +} + diff --git a/tests/core/domains/zonotope/codac2_tests_Zonotope.py b/tests/core/domains/zonotope/codac2_tests_Zonotope.py new file mode 100644 index 000000000..46ddd969a --- /dev/null +++ b/tests/core/domains/zonotope/codac2_tests_Zonotope.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +# Codac tests +# ---------------------------------------------------------------------------- +# \date 2025 +# \author Maël Godard +# \copyright Copyright 2024 Codac Team +# \license GNU Lesser General Public License (LGPL) + +import unittest +from codac import * +import sys +import math + +class TestZonotope(unittest.TestCase): + + def test_zonotope(self): + + Z1 = Zonotope(Vector([2,1]), Matrix([[0.2 ,0.08], [0.04,0.18]])) + Z2 = Zonotope(Vector([2,0.5]), Matrix([[-0.2], [0.1]])) + Zs = Z1+Z2 + + c = Vector([4,1.5]) + A = Matrix([[0.2 ,0.08, -0.2], + [0.04, 0.18, 0.1]]) + self.assertTrue(Zs.c == c) + self.assertTrue(Zs.A == A) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/core/peibos/codac2_tests_peibos.cpp b/tests/core/peibos/codac2_tests_peibos.cpp index bda717048..755b741e7 100644 --- a/tests/core/peibos/codac2_tests_peibos.cpp +++ b/tests/core/peibos/codac2_tests_peibos.cpp @@ -69,12 +69,12 @@ TEST_CASE("Peibos") CHECK(v_par_3d.size() == 6); - CHECK(Approx(v_par_3d[0].z,1e-6) == Vector({1.,0.,0.})); - CHECK(Approx(v_par_3d[1].z,1e-6) == Vector({0.,1.,0.})); - CHECK(Approx(v_par_3d[2].z,1e-6) == Vector({-1.,0.,0.})); - CHECK(Approx(v_par_3d[3].z,1e-6) == Vector({0.,-1.,0.})); - CHECK(Approx(v_par_3d[4].z,1e-6) == Vector({0.,0.,-1.})); - CHECK(Approx(v_par_3d[5].z,1e-6) == Vector({0.,0.,1.})); + CHECK(Approx(v_par_3d[0].c,1e-6) == Vector({1.,0.,0.})); + CHECK(Approx(v_par_3d[1].c,1e-6) == Vector({0.,1.,0.})); + CHECK(Approx(v_par_3d[2].c,1e-6) == Vector({-1.,0.,0.})); + CHECK(Approx(v_par_3d[3].c,1e-6) == Vector({0.,-1.,0.})); + CHECK(Approx(v_par_3d[4].c,1e-6) == Vector({0.,0.,-1.})); + CHECK(Approx(v_par_3d[5].c,1e-6) == Vector({0.,0.,1.})); double a = 4.35066; diff --git a/tests/core/peibos/codac2_tests_peibos.py b/tests/core/peibos/codac2_tests_peibos.py index 66042d8e0..f4f12191e 100644 --- a/tests/core/peibos/codac2_tests_peibos.py +++ b/tests/core/peibos/codac2_tests_peibos.py @@ -63,12 +63,12 @@ def test_peibos(self): self.assertTrue(len(v_par_3d) == 6) - self.assertTrue(Approx(v_par_3d[0].z,1e-6) == Vector([1.,0.,0.])) - self.assertTrue(Approx(v_par_3d[1].z,1e-6) == Vector([0.,1.,0.])) - self.assertTrue(Approx(v_par_3d[2].z,1e-6) == Vector([-1,0.,0.])) - self.assertTrue(Approx(v_par_3d[3].z,1e-6) == Vector([0.,-1.,0.])) - self.assertTrue(Approx(v_par_3d[4].z,1e-6) == Vector([0.,0.,-1.])) - self.assertTrue(Approx(v_par_3d[5].z,1e-6) == Vector([0.,0.,1.])) + self.assertTrue(Approx(v_par_3d[0].c,1e-6) == Vector([1.,0.,0.])) + self.assertTrue(Approx(v_par_3d[1].c,1e-6) == Vector([0.,1.,0.])) + self.assertTrue(Approx(v_par_3d[2].c,1e-6) == Vector([-1,0.,0.])) + self.assertTrue(Approx(v_par_3d[3].c,1e-6) == Vector([0.,-1.,0.])) + self.assertTrue(Approx(v_par_3d[4].c,1e-6) == Vector([0.,0.,-1.])) + self.assertTrue(Approx(v_par_3d[5].c,1e-6) == Vector([0.,0.,1.])) a = 4.35066