From abd2416ed80447936554204248c703b54cd30989 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 31 Mar 2026 20:52:44 +0200 Subject: [PATCH 1/4] [doc] added CtcInter in manual --- doc/manual/index.rst | 2 +- doc/manual/manual/contractors/index.rst | 129 ++++++++++++- .../manual/contractors/set/ctcinter.rst | 95 ++++++++++ doc/manual/manual/contractors/set/index.rst | 12 ++ doc/manual/manual/contractors/set/src.cpp | 41 +++++ doc/manual/manual/contractors/set/src.py | 43 +++++ .../core/contractors/codac2_py_CtcInter.cpp | 2 +- src/core/contractors/codac2_CtcInter.h | 174 ++++++++++++++++-- tests/CMakeLists.txt | 1 + 9 files changed, 485 insertions(+), 14 deletions(-) create mode 100644 doc/manual/manual/contractors/set/ctcinter.rst create mode 100644 doc/manual/manual/contractors/set/index.rst create mode 100644 doc/manual/manual/contractors/set/src.cpp create mode 100644 doc/manual/manual/contractors/set/src.py diff --git a/doc/manual/index.rst b/doc/manual/index.rst index d4c6b7c04..6d3d99c1e 100644 --- a/doc/manual/index.rst +++ b/doc/manual/index.rst @@ -233,8 +233,8 @@ User manual * CtcGaussSeidel * CtcLinearPrecond * Set contractors + * :ref:`sec-ctc-set-ctcinter` * CtcUnion - * CtcInter * CtcQInter * CtcCartProd * CtcProj diff --git a/doc/manual/manual/contractors/index.rst b/doc/manual/manual/contractors/index.rst index e86d51bdc..2ad26e463 100644 --- a/doc/manual/manual/contractors/index.rst +++ b/doc/manual/manual/contractors/index.rst @@ -4,6 +4,7 @@ Contractors, separators .. toctree:: + CtcInter CtcInverse CtcDist CtcPolar @@ -17,4 +18,130 @@ Contractors, separators .. analytic/index.rst .. geometric/index.rst .. shape/index.rst -.. temporal/index.rst \ No newline at end of file +.. temporal/index.rst + + + +Overview of contractors and separators +-------------------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - **Contractors** + - **Separators** + + * - ``CtcIdentity`` + - — + + * - ``CtcEmpty`` + - — + + * - ``CtcLazy`` + - — + + * - ``CtcFixpoint`` + - — + + * - ``CtcGaussElim`` + - — + + * - ``CtcGaussSeidel`` + - — + + * - ``CtcLinearPrecond`` + - — + + * - ``CtcUnion`` + - ``SepUnion`` + + * - :ref:`CtcInter ` + - ``SepInter`` + + * - ``CtcQInter`` + - ``SepQInter`` + + * - ``CtcCartProd`` + - ``SepCartProd`` + + * - ``CtcProj`` + - ``SepProj`` + + * - ``CtcNot`` + - ``SepNot`` + + * - ``CtcAction`` + - ``SepAction`` + + * - :ref:`CtcInverse ` + - ``SepInverse`` + + * - ``CtcInverseNotIn`` + - — + + * - — + - ``SepTransform`` + + * - :ref:`CtcDist ` + - — + + * - :ref:`CtcPolar ` + - ``SepPolarCart`` / ``SepCartPolar`` + + * - ``CtcSegment`` + - — + + * - ``CtcPolygon`` + - ``SepPolygon`` + + * - ``CtcPointCloud`` + - — + + * - ``CtcEllipse`` + - ``SepEllipse`` + + * - ``CtcCross`` / ``CtcNoCross`` + - ``SepCross`` + + * - ``CtcCtcBoundary`` + - ``SepCtcBoundary`` + + * - ``CtcWrapper`` + - ``SepWrapper`` + + * - ``CtcImage`` + - ``SepImage`` + + * - ``CtcDiscreteSet`` + - — + + * - ``CtcDeriv`` + - — + + * - ``CtcEval`` + - — + + * - ``CtcDelay`` + - — + + * - ``CtcLinobs`` + - — + + * - ``CtcLohner`` + - — + + * - ``CtcPicard`` + - — + + * - ``CtcChain`` + - — + + * - ``CtcDiffInclusion`` + - — + + * - — + - ``SepCtcPair`` + + * - ``CtcInnerOuter`` + - — diff --git a/doc/manual/manual/contractors/set/ctcinter.rst b/doc/manual/manual/contractors/set/ctcinter.rst new file mode 100644 index 000000000..248c63d8d --- /dev/null +++ b/doc/manual/manual/contractors/set/ctcinter.rst @@ -0,0 +1,95 @@ +.. _sec-ctc-set-ctcinter: + +The CtcInter contractor +======================= + + Main author: `Simon Rohou `_ + + +.. doxygenclass:: codac2::CtcInter + :project: codac + +Basic usage +----------- + +The most common way to create an intersection contractor is to combine two existing +contractors with ``&``. + +.. tabs:: + + .. group-tab:: Python + + .. literalinclude:: src.py + :language: py + :start-after: [ctcinter-1-beg] + :end-before: [ctcinter-1-end] + :dedent: 2 + + .. group-tab:: C++ + + .. literalinclude:: src.cpp + :language: c++ + :start-after: [ctcinter-1-beg] + :end-before: [ctcinter-1-end] + :dedent: 2 + +Once built, the contractor can be applied as any other box contractor. + +.. tabs:: + + .. group-tab:: Python + + .. literalinclude:: src.py + :language: py + :start-after: [ctcinter-2-beg] + :end-before: [ctcinter-2-end] + :dedent: 2 + + .. group-tab:: C++ + + .. literalinclude:: src.cpp + :language: c++ + :start-after: [ctcinter-2-beg] + :end-before: [ctcinter-2-end] + :dedent: 2 + +In this example, ``c1`` restricts the box to :math:`[-10,10]\times[-2,2]` and ``c2`` +restricts it to :math:`[-12,2]\times[0,4]`. Their conjunction therefore contracts the +initial box to: + +.. math:: + + [-10,10]\times[-2,2] \ \cap \ [-12,2]\times[0,4] + \,=\, [-10,2]\times[0,2]. + +Building a conjunction incrementally +------------------------------------ + +A ``CtcInter`` may also be created from a prescribed domain size and then populated later. +In that case, the object is initially neutral: as long as no sub-contractor is added, it +has no effect on the contracted box. + +.. tabs:: + + .. group-tab:: Python + + .. literalinclude:: src.py + :language: py + :start-after: [ctcinter-3-beg] + :end-before: [ctcinter-3-end] + :dedent: 2 + + .. group-tab:: C++ + + .. literalinclude:: src.cpp + :language: c++ + :start-after: [ctcinter-3-beg] + :end-before: [ctcinter-3-end] + :dedent: 2 + +The method ``nb()`` returns the current number of sub-contractors stored in the +intersection. + +.. admonition:: Technical documentation + + See the `C++ API documentation of this class <../../api/html/classcodac2_1_1_ctc_inter.html>`_. diff --git a/doc/manual/manual/contractors/set/index.rst b/doc/manual/manual/contractors/set/index.rst new file mode 100644 index 000000000..908dec14b --- /dev/null +++ b/doc/manual/manual/contractors/set/index.rst @@ -0,0 +1,12 @@ +Set contractors +=============== + +.. toctree:: + + CtcInter + CtcUnion + CtcQInter + CtcCartProd + CtcProj + CtcNot + CtcAction \ No newline at end of file diff --git a/doc/manual/manual/contractors/set/src.cpp b/doc/manual/manual/contractors/set/src.cpp new file mode 100644 index 000000000..c8ebe6546 --- /dev/null +++ b/doc/manual/manual/contractors/set/src.cpp @@ -0,0 +1,41 @@ +/** + * Codac tests + * ---------------------------------------------------------------------------- + * \date 2026 + * \author Simon Rohou + * \copyright Copyright 2026 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#include +#include + +using namespace std; +using namespace codac2; + +TEST_CASE("CtcInter - manual") +{ + // [ctcinter-1-beg] + CtcWrapper c1(IntervalVector({{-10,10},{-2,2}})); + CtcWrapper c2(IntervalVector({{-12,2},{0,4}})); + + auto c3 = c1 & c2; + // c3 is a CtcInter gathering the two contractors. + // [ctcinter-1-end] + + // [ctcinter-2-beg] + IntervalVector x({{-oo,oo},{-oo,oo}}); + c3.contract(x); + // x = [ [-10, 2] ; [0, 2] ] + // [ctcinter-2-end] + + // [ctcinter-3-beg] + CtcInter c4(2); // initially neutral conjunction on 2d boxes + c4 &= c1; + c4 &= c2; + + auto n = c4.nb(); + // n = 2 + // [ctcinter-3-end] + CHECK(n == 2); +} diff --git a/doc/manual/manual/contractors/set/src.py b/doc/manual/manual/contractors/set/src.py new file mode 100644 index 000000000..0fb5509d9 --- /dev/null +++ b/doc/manual/manual/contractors/set/src.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +# Codac tests +# ---------------------------------------------------------------------------- +# \date 2026 +# \author Simon Rohou +# \copyright Copyright 2026 Codac Team +# \license GNU Lesser General Public License (LGPL) + +import sys, os +import unittest +import math +from codac import * + +class TestCtcSetManual(unittest.TestCase): + + def tests_CtcInter_manual(test): + + # [ctcinter-1-beg] + c1 = CtcWrapper([[-10,10],[-2,2]]) + c2 = CtcWrapper([[-12,2],[0,4]]) + + c3 = c1 & c2 + # c3 is a CtcInter gathering the two contractors. + # [ctcinter-1-end] + + # [ctcinter-2-beg] + x = IntervalVector([[-oo,oo],[-oo,oo]]) + c3.contract(x) + # x = [ [-10, 2] ; [0, 2] ] + # [ctcinter-2-end] + + # [ctcinter-3-beg] + c4 = CtcInter(2) # initially neutral conjunction on 2d boxes + c4 &= c1 + c4 &= c2 + + n = c4.nb() + # n = 2 + # [ctcinter-3-end] + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/python/src/core/contractors/codac2_py_CtcInter.cpp b/python/src/core/contractors/codac2_py_CtcInter.cpp index aece02518..c27853069 100644 --- a/python/src/core/contractors/codac2_py_CtcInter.cpp +++ b/python/src/core/contractors/codac2_py_CtcInter.cpp @@ -51,7 +51,7 @@ void export_CtcInter(py::module& m, py::class_,pyCtcInte SIZET_CTCINTER_X_NB_CONST) .def(CONTRACT_BOX_METHOD(CtcInter, - VOID_CTCINTER_X_CONTRACT_IMPL_X__REF_CONST)) + VOID_CTCINTER_X_CONTRACT_X_REF_VARIADIC_CONST)) .def("__iand__", [](CtcInter& c1, const CtcBase& c2) { diff --git a/src/core/contractors/codac2_CtcInter.h b/src/core/contractors/codac2_CtcInter.h index 8eaa29de9..7e59ba1d4 100644 --- a/src/core/contractors/codac2_CtcInter.h +++ b/src/core/contractors/codac2_CtcInter.h @@ -16,11 +16,55 @@ namespace codac2 { + /** + * \class CtcInter + * \brief Sequential intersection of several contractors: + * @f[ + * \mathcal{C}_{\mathrm{inter}} = \mathcal{C}_1 \cap \mathcal{C}_2 \cap \dots \cap \mathcal{C}_n. + * @f] + * + * Each sub-contractor is applied successively to the current domain. + * If two contractors implement two constraints, then their intersection corresponds to the + * logical conjunction of these constraints. This corresponds + * to the classical intersection/composition pattern of contractor programming. + * + * ``CtcInter`` stores a collection of contractors acting on the same contracted types and + * applies them one after the other. For instance, for contractors acting on a single box \f$[\mathbf{x}]\f$: + * @f[ + * \left(\mathcal{C}_1 \cap \mathcal{C}_2\right)([\mathbf{x}]) + * := \mathcal{C}_1([\mathbf{x}]) \cap \mathcal{C}_2([\mathbf{x}]). + * @f] + * + * In practice, each stored contractor contracts the current domain in place; the next one + * then works on the already reduced result. It does not perform any fixpoint iteration. + * If the domain becomes empty at some step, the + * contraction stops immediately. + * + * A ``CtcInter`` object can be built explicitly, extended incrementally with ``&=``, + * or constructed implicitly with the binary ``&`` operator between two contractors. + * + * In C++, a variadic ``.contract(..)`` function is available when the intersected contractors + * act on several domains rather than on a single box. Such contractors can be combined provided + * they are homogeneous, *i.e.* they act on the same sequence of input types. + * + * \tparam X Contracted domain type(s). For the common box-contractor case, this is typically + * ``IntervalVector``. + */ template class CtcInter : public Ctc,X...> { public: + /** + * \brief Builds a neutral intersection contractor with a prescribed domain size. + * + * This constructor is mainly useful when building a contractor incrementally with + * ``operator&=``. Otherwise it has no effect. + * + * \param n Dimension of the contracted object. + * + * \note When ``X...`` is ``Interval``, the size must be ``1``. + */ explicit CtcInter(Index n) : Ctc,X...>(n) { @@ -30,12 +74,28 @@ namespace codac2 } } + /** + * \brief Builds an intersection contractor from a single contractor. + * + * The contractor is stored internally in the collection of composed contractors. + * + * \tparam C Type of the contractor or contractor pointer. + * \param c Contractor to store. + */ template requires (IsCtcBaseOrPtr && !std::is_same_v,C>) CtcInter(const C& c) : Ctc,X...>(size_of(c)), _ctcs(c) { } + /** + * \brief Builds an intersection contractor from several contractors. + * + * All contractors must act on contracted objects of the same size. + * + * \tparam C Contractor or contractor-pointer types. + * \param c Contractors to compose sequentially. + */ template requires (IsCtcBaseOrPtr && ...) CtcInter(const C&... c) @@ -44,28 +104,44 @@ namespace codac2 assert_release(all_same_size(c...)); } + /** + * \brief Returns the number of stored contractors. + * + * \return Size of the internal contractor collection. + */ size_t nb() const { return _ctcs.size(); } - template // single type - void contract_impl(X_& x) const + /** + * \brief Contracts the given domain(s) by applying all stored contractors in sequence. + * + * The domains are updated in place. If one contractor empties one of the domains, the remaining + * contractors are not evaluated. + * + * \param x Domain(s) to contract. + */ + void contract(X&... x) const { for(const auto& ci : _ctcs) { - ci->contract(x); - if(x.is_empty()) + ci->contract(x...); + if((x.is_empty() | ...)) return; } } - void contract(X&... x) const - { - // contract_impl(..) method for multiple types is not yet implemented - contract_impl(x...); - } - + /** + * \brief Appends a contractor to the current intersection. + * + * The contractor is added at the end of the internal sequence, so it will be applied + * after the already stored ones. + * + * \tparam C Type of the contractor or contractor pointer. + * \param c Contractor to append. + * \return A reference to ``*this``. + */ template requires IsCtcBaseOrPtr CtcInter& operator&=(const C& c) @@ -77,45 +153,110 @@ namespace codac2 protected: + /** \brief Internal collection of contractors composing the intersection. */ Collection> _ctcs; }; + /** + * \brief Default ``CtcInter`` specialization for box contractors. + * + * ``CtcInter<>`` is an alias-like specialization inheriting from + * ``CtcInter``. + */ template <> class CtcInter<> : public CtcInter { }; + /** + * \brief Helper meta-function returning the appropriate ``CtcInter`` type from a tuple. + * + * \tparam Tuple Tuple of contracted types. + */ template struct CtcInterType; + /** + * \brief ``CtcInterType`` specialization for tuples of contracted types. + * + * \tparam T Contracted types extracted from the tuple. + */ template struct CtcInterType> { using Ctc = CtcInter; }; + /** + * \brief Builds an intersection contractor from two contractors. + * + * This overload enables the natural syntax ``c1 & c2``. + * + * \tparam C1 Type of the first contractor. + * \tparam C2 Type of the second contractor. + * \param c1 First contractor. + * \param c2 Second contractor. + * \return The intersection contractor storing ``c1`` and ``c2``. + */ template typename CtcInterType::Ctc operator&(const C1& c1, const C2& c2) { return { c1, c2 }; } + /** + * \brief Builds an intersection contractor from two shared contractor pointers. + * + * \tparam C1 Type of the first pointed contractor. + * \tparam C2 Type of the second pointed contractor. + * \param c1 Shared pointer to the first contractor. + * \param c2 Shared pointer to the second contractor. + * \return The resulting intersection contractor. + */ template typename CtcInterType::Ctc operator&(const std::shared_ptr& c1, const std::shared_ptr& c2) { return { c1, c2 }; } + /** + * \brief Builds an intersection contractor from a shared contractor pointer and a contractor. + * + * \tparam C1 Type of the first pointed contractor. + * \tparam C2 Type of the second contractor. + * \param c1 Shared pointer to the first contractor. + * \param c2 Second contractor. + * \return The resulting intersection contractor. + */ template typename CtcInterType::Ctc operator&(const std::shared_ptr& c1, const C2& c2) { return { c1, c2 }; } + /** + * \brief Builds an intersection contractor from a contractor and a shared contractor pointer. + * + * \tparam C1 Type of the first contractor. + * \tparam C2 Type of the second pointed contractor. + * \param c1 First contractor. + * \param c2 Shared pointer to the second contractor. + * \return The resulting intersection contractor. + */ template typename CtcInterType::Ctc operator&(const C1& c1, const std::shared_ptr& c2) { return { c1, c2 }; } + /** + * \brief Intersects a box with a contractor by wrapping the box into a ``CtcWrapper``. + * + * This overload enables expressions such as ``box & ctc``. + * + * \tparam C2 Type of the contractor. + * \param c1 Box interpreted as a wrapper contractor. + * \param c2 Contractor. + * \return The resulting box-contractor intersection. + */ template requires std::is_base_of_v,C2> inline CtcInter operator&(const IntervalVector& c1, const C2& c2) @@ -124,6 +265,16 @@ namespace codac2 return CtcInter(CtcWrapper(c1),c2); } + /** + * \brief Intersects a contractor with a box by wrapping the box into a ``CtcWrapper``. + * + * This overload enables expressions such as ``ctc & box``. + * + * \tparam C1 Type of the contractor. + * \param c1 Contractor. + * \param c2 Box interpreted as a wrapper contractor. + * \return The resulting box-contractor intersection. + */ template requires std::is_base_of_v,C1> inline CtcInter operator&(const C1& c1, const IntervalVector& c2) @@ -133,5 +284,6 @@ namespace codac2 } // Template deduction guides + CtcInter(Index) -> CtcInter; -} \ No newline at end of file +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b3eded7af..38f23e0ec 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -43,6 +43,7 @@ list(APPEND SRC_TESTS # listing files without extension core/contractors/codac2_tests_linear_ctc ../doc/manual/manual/contractors/geometric/src ../doc/manual/manual/contractors/analytic/src + ../doc/manual/manual/contractors/set/src core/domains/codac2_tests_BoolInterval core/domains/ellipsoid/codac2_tests_Ellipsoid From c5cd75fa1f020f0a6774a40f062ebb97d0d0c11c Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 31 Mar 2026 20:53:11 +0200 Subject: [PATCH 2/4] [ctc] variadic version of CtcUnion::contract(..) for multiple domains --- .../core/contractors/codac2_py_CtcUnion.cpp | 2 +- src/core/contractors/codac2_CtcUnion.h | 35 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/python/src/core/contractors/codac2_py_CtcUnion.cpp b/python/src/core/contractors/codac2_py_CtcUnion.cpp index 623c175ea..0af26087c 100644 --- a/python/src/core/contractors/codac2_py_CtcUnion.cpp +++ b/python/src/core/contractors/codac2_py_CtcUnion.cpp @@ -51,7 +51,7 @@ void export_CtcUnion(py::module& m, py::class_,pyCtcInte SIZET_CTCUNION_X_NB_CONST) .def(CONTRACT_BOX_METHOD(CtcUnion, - VOID_CTCUNION_X_CONTRACT_IMPL_X__REF_CONST)) + VOID_CTCUNION_X_CONTRACT_X_REF_VARIADIC_CONST)) .def("__ior__", [](CtcUnion& c1, const CtcBase& c2) { diff --git a/src/core/contractors/codac2_CtcUnion.h b/src/core/contractors/codac2_CtcUnion.h index ee1060de1..238934607 100644 --- a/src/core/contractors/codac2_CtcUnion.h +++ b/src/core/contractors/codac2_CtcUnion.h @@ -9,6 +9,7 @@ #pragma once +#include #include #include "codac2_CtcWrapper.h" #include "codac2_Collection.h" @@ -47,26 +48,32 @@ namespace codac2 return _ctcs.size(); } - template // single type - void contract_impl(X_& x) const + void contract(X&... x) const { - auto result = x; - result.set_empty(); + auto result = std::tuple(x...); + std::apply([](auto&... xi) + { + (xi.set_empty(), ...); + }, result); + + auto accumulate_union = [&](const std::tuple& y, std::index_sequence) + { + ((std::get(result) |= std::get(y)), ...); + }; for(const auto& ci : _ctcs) { - auto saved_x = x; - ci->contract(saved_x); - result |= saved_x; - } + auto saved = std::tuple(x...); - x = result; - } + std::apply([&](auto&... xi) + { + ci->contract(xi...); + }, saved); - void contract(X&... x) const - { - // contract_impl(..) method for multiple types is not yet implemented - contract_impl(x...); + accumulate_union(saved, std::index_sequence_for{}); + } + + std::tie(x...) = result; } template From efab191f48a9307fe9a19c09e96a6594d37ccccd Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Fri, 3 Apr 2026 15:47:36 +0200 Subject: [PATCH 3/4] [cmake] corrected linking problems with CAPD and SYMPY extensions --- doc/manual/manual/extensions/capd/index.rst | 12 +++++++++ doc/manual/manual/extensions/sympy/index.rst | 14 ++++++++++ examples/05_capd_solver/CMakeLists.txt | 9 +++++-- examples/12_peibos_capd/CMakeLists.txt | 9 +++++-- src/CMakeLists.txt | 27 ++------------------ 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/doc/manual/manual/extensions/capd/index.rst b/doc/manual/manual/extensions/capd/index.rst index 3bb0b4a0c..17ccff750 100644 --- a/doc/manual/manual/extensions/capd/index.rst +++ b/doc/manual/manual/extensions/capd/index.rst @@ -51,6 +51,18 @@ The header of the ``codac-capd`` extension is not included by default. You need #include #include +Furthermore, you need to link the extension to your project, for instance by updating your ``CMakeLists.txt`` with:: + + 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} ${CODAC_CAPD_INCLUDE_DIR}) + target_link_libraries(${PROJECT_NAME} PRIVATE + ${CODAC_LIBRARIES} + ${CODAC_CAPD_LIBRARY} # linking to the codac-capd extension + capd::capd # linking to CAPD + Ibex::ibex + ) + You can use the functions ``to_capd`` and ``to_codac`` to convert between CAPD and Codac objects as follows: .. tabs:: diff --git a/doc/manual/manual/extensions/sympy/index.rst b/doc/manual/manual/extensions/sympy/index.rst index 3ec521785..c1e6b890c 100644 --- a/doc/manual/manual/extensions/sympy/index.rst +++ b/doc/manual/manual/extensions/sympy/index.rst @@ -43,6 +43,20 @@ The same package is also required by the C++ extension, since the symbolic backe The Python interpreter is managed internally by the extension in C++, and is of course already available when Codac is used from Python. No explicit interpreter initialization is needed in user code. +In C++ however, you need to link the extension to your project, for instance by updating your ``CMakeLists.txt`` with:: + + find_package(pybind11) + + 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} ${CODAC_SYMPY_INCLUDE_DIR}) + target_link_libraries(${PROJECT_NAME} PRIVATE + ${CODAC_LIBRARIES} + ${CODAC_SYMPY_LIBRARY} # linking to the codac-sympy extension + pybind11::embed # linking to pybind11 + Ibex::ibex + ) + Finally, in order to include the features of the extension: .. tabs:: diff --git a/examples/05_capd_solver/CMakeLists.txt b/examples/05_capd_solver/CMakeLists.txt index dfb06629e..4d720d238 100644 --- a/examples/05_capd_solver/CMakeLists.txt +++ b/examples/05_capd_solver/CMakeLists.txt @@ -36,5 +36,10 @@ 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 +target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS} ${CODAC_CAPD_INCLUDE_DIR}) +target_link_libraries(${PROJECT_NAME} PRIVATE + ${CODAC_LIBRARIES} + ${CODAC_CAPD_LIBRARY} + capd::capd + Ibex::ibex +) \ No newline at end of file diff --git a/examples/12_peibos_capd/CMakeLists.txt b/examples/12_peibos_capd/CMakeLists.txt index cf9ef35ce..9091ca50a 100644 --- a/examples/12_peibos_capd/CMakeLists.txt +++ b/examples/12_peibos_capd/CMakeLists.txt @@ -30,5 +30,10 @@ 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}) \ No newline at end of file + target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS} ${CODAC_CAPD_INCLUDE_DIR}) + target_link_libraries(${PROJECT_NAME} PRIVATE + ${CODAC_LIBRARIES} + ${CODAC_CAPD_LIBRARY} + capd::capd + Ibex::ibex + ) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9843f864e..28fd1c4fc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -77,24 +77,6 @@ set(CODAC_CXX_FLAGS \"\") ") - #if(WITH_PYTHON) - # - # file(APPEND ${CODAC_CMAKE_CONFIG_FILE} " - # - ## Adding Sympy interface: - # - # find_path(CODAC_SYMPY_INCLUDE_DIR ${PROJECT_NAME}-sympy.h - # PATH_SUFFIXES include/${PROJECT_NAME}-sympy) - # - # find_library(CODAC_SYMPY_LIBRARY NAMES ${PROJECT_NAME}-sympy - # PATH_SUFFIXES lib) - # - # set(CODAC_LIBRARIES \${CODAC_LIBRARIES} \${CODAC_SYMPY_LIBRARY} pybind11::embed \${CODAC_SYMPY_LIBRARY} pybind11::embed) - # set(CODAC_INCLUDE_DIRS \${CODAC_INCLUDE_DIRS} \${CODAC_SYMPY_INCLUDE_DIR}) - # ") - # - #endif() - if(WITH_PYTHON) file(APPEND ${CODAC_CMAKE_CONFIG_FILE} " @@ -103,12 +85,10 @@ find_path(CODAC_SYMPY_INCLUDE_DIR ${PROJECT_NAME}-sympy.h PATH_SUFFIXES include/${PROJECT_NAME}-sympy) - set(CODAC_INCLUDE_DIRS \${CODAC_INCLUDE_DIRS} \${CODAC_SYMPY_INCLUDE_DIR}) - find_library(CODAC_SYMPY_LIBRARY NAMES ${PROJECT_NAME}-sympy PATH_SUFFIXES lib) - set(CODAC_LIBRARIES \${CODAC_LIBRARIES} \${CODAC_SYMPY_LIBRARY}) + set(CODAC_SYMPY_LIBRARY \${CODAC_SYMPY_LIBRARY} \${CODAC_LIBRARIES}) ") endif() @@ -120,15 +100,12 @@ # Optional 3rd party: find_package(CAPD REQUIRED) - find_path(CODAC_CAPD_INCLUDE_DIR ${PROJECT_NAME}-capd.h PATH_SUFFIXES include/${PROJECT_NAME}-capd) - set(CODAC_INCLUDE_DIRS \${CODAC_INCLUDE_DIRS} \${CODAC_CAPD_INCLUDE_DIR}) - find_library(CODAC_CAPD_LIBRARY NAMES ${PROJECT_NAME}-capd PATH_SUFFIXES lib) - set(CODAC_LIBRARIES \${CODAC_LIBRARIES} \${CODAC_CAPD_LIBRARY} capd::capd) + set(CODAC_CAPD_LIBRARY \${CODAC_CAPD_LIBRARY} \${CODAC_LIBRARIES}) ") endif() From 1ff3b92f313d7d24a1da85997be90ce588e67be2 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Fri, 3 Apr 2026 15:48:14 +0200 Subject: [PATCH 4/4] [examples] added one simple Sympy example --- examples/14_sympy/CMakeLists.txt | 41 ++++++++++++++++++++++++++++++++ examples/14_sympy/main.cpp | 17 +++++++++++++ examples/14_sympy/main.py | 11 +++++++++ 3 files changed, 69 insertions(+) create mode 100644 examples/14_sympy/CMakeLists.txt create mode 100644 examples/14_sympy/main.cpp create mode 100644 examples/14_sympy/main.py diff --git a/examples/14_sympy/CMakeLists.txt b/examples/14_sympy/CMakeLists.txt new file mode 100644 index 000000000..52197a061 --- /dev/null +++ b/examples/14_sympy/CMakeLists.txt @@ -0,0 +1,41 @@ +# ================================================================== +# codac / basics example - cmake configuration file +# ================================================================== + + cmake_minimum_required(VERSION 3.5) + project(codac_example LANGUAGES CXX) + + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# 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}") + +# Initializating Ibex + + ibex_init_common() + +# 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() + + find_package(pybind11) + + 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} ${CODAC_SYMPY_INCLUDE_DIR}) + target_link_libraries(${PROJECT_NAME} PRIVATE + ${CODAC_LIBRARIES} + ${CODAC_SYMPY_LIBRARY} # linking to the codac-sympy extension + pybind11::embed # linking to pybind11 + Ibex::ibex + ) \ No newline at end of file diff --git a/examples/14_sympy/main.cpp b/examples/14_sympy/main.cpp new file mode 100644 index 000000000..c909ba181 --- /dev/null +++ b/examples/14_sympy/main.cpp @@ -0,0 +1,17 @@ +#include +#include + +using namespace std; +using namespace codac2; + +int main() +{ + ScalarVar x,y; + AnalyticFunction f({x,y}, x*y + sin(x)); + + auto dfdx = sympy_partial_diff(f,x); + auto dfdy = sympy_partial_diff(f,y); + + cout << dfdx << endl; + cout << dfdy << endl; +} \ No newline at end of file diff --git a/examples/14_sympy/main.py b/examples/14_sympy/main.py new file mode 100644 index 000000000..0da59e29b --- /dev/null +++ b/examples/14_sympy/main.py @@ -0,0 +1,11 @@ +from codac import * + +x = ScalarVar() +y = ScalarVar() +f = AnalyticFunction([x,y], x*y + sin(x)) + +dfdx = sympy_partial_diff(f, x) +dfdy = sympy_partial_diff(f, y) + +print(dfdx) +print(dfdy) \ No newline at end of file