From 2a4fadd3fff8d196e0e68b0d16154d6516bd7b1f Mon Sep 17 00:00:00 2001 From: SimonRohou Date: Sat, 24 Feb 2024 12:13:32 +0100 Subject: [PATCH] [codac2] new developments --- python/src/core/2/cn/codac2_py_Contractor.cpp | 6 +- .../core/2/cn/codac2_py_ContractorNetwork.cpp | 4 +- src/core/2/cn/codac2_Contractor.cpp | 32 --- src/core/2/cn/codac2_Contractor.h | 63 ---- src/core/2/cn/codac2_ContractorNetwork.cpp | 175 ++++++++---- src/core/2/cn/codac2_ContractorNetwork.h | 70 +++-- src/core/2/cn/codac2_ContractorNode.cpp | 13 - src/core/2/cn/codac2_ContractorNode.h | 153 +++++++--- src/core/2/cn/codac2_DomainCaster.cpp | 50 ++++ src/core/2/cn/codac2_DomainCaster.h | 259 +++++++++++++++++ src/core/2/cn/codac2_DomainNode.cpp | 12 - src/core/2/cn/codac2_DomainNode.h | 111 +++---- src/core/2/cn/codac2_PropagationSpan.cpp | 227 +++++++++++++++ src/core/2/cn/codac2_PropagationSpan.h | 243 ++++++++++++++++ src/core/2/cn/codac2_Var.cpp | 19 ++ src/core/2/cn/codac2_Var.h | 82 ++++-- src/core/2/contractors/codac2_Ctc.h | 204 +++++++++++++ src/core/2/contractors/codac2_CtcCN.cpp | 30 ++ src/core/2/contractors/codac2_CtcCN.h | 42 ++- src/core/2/contractors/codac2_CtcDeriv.h | 61 ++++ .../2/contractors/codac2_CtcDiffInclusion.h | 2 +- src/core/2/contractors/codac2_CtcDist.cpp | 55 ++++ src/core/2/contractors/codac2_CtcDist.h | 37 +++ src/core/2/contractors/codac2_CtcInter.cpp | 25 ++ src/core/2/contractors/codac2_CtcInter.h | 32 ++- src/core/2/contractors/codac2_CtcNoCross.cpp | 44 +++ src/core/2/contractors/codac2_CtcNoCross.h | 45 +++ src/core/2/contractors/codac2_CtcPaver.h | 94 ++++-- src/core/2/contractors/codac2_CtcPolar.cpp | 35 +++ src/core/2/contractors/codac2_CtcPolar.h | 37 +++ src/core/2/contractors/codac2_CtcUnion.h | 84 ++++++ .../2/contractors/codac2_arithmetic_ctc.cpp | 23 ++ .../2/contractors/codac2_arithmetic_ctc.h | 142 +++++++++ src/core/2/contractors/codac2_linear_ctc.cpp | 54 ++++ src/core/2/contractors/codac2_linear_ctc.h | 179 ++++++++++++ src/core/2/domains/interval/codac2_Interval.h | 2 + .../domains/interval/codac2_IntervalMatrix.h | 12 +- .../interval/codac2_IntervalVector.cpp | 270 ++++++++++++++++++ .../domains/interval/codac2_IntervalVector.h | 4 +- .../interval/codac2_IntervalVectorComponent.h | 193 +++++++++++++ .../2/domains/interval/codac2_cart_prod.h | 2 +- src/core/2/domains/paving/codac2_Paving.cpp | 20 ++ src/core/2/domains/paving/codac2_Paving.h | 143 +++++++--- src/core/2/domains/tube/codac2_TDomain.cpp | 2 +- src/core/2/domains/tube/codac2_TDomain.h | 1 - src/core/2/domains/tube/codac2_Tube.h | 15 +- .../2/domains/tube/codac2_TubeEvaluation.h | 10 +- src/core/2/tools/codac2_isbaseof.h | 21 ++ src/core/2/tools/codac2_tuples.h | 19 ++ src/core/2/variables/codac2_Matrix.h | 5 +- src/core/2/variables/codac2_Vector.h | 4 +- src/core/CMakeLists.txt | 41 ++- src/core/contractors/static/codac_CtcUnion.h | 2 +- src/core/functions/codac_TFunction.h | 2 +- tests/catch/catch_interval.hpp | 27 ++ tests/core/CMakeLists.txt | 10 +- tests/core/tests_codac2_CtcUnion.cpp | 18 ++ tests/core/tests_codac2_cn.cpp | 128 +++++++++ tests/core/tests_codac2_intervalvector.cpp | 6 +- tests/core/tests_codac2_tubes.cpp | 72 +++-- .../tests_codac2_tubes_templated_types.cpp | 4 +- 61 files changed, 3277 insertions(+), 500 deletions(-) delete mode 100644 src/core/2/cn/codac2_Contractor.cpp delete mode 100644 src/core/2/cn/codac2_Contractor.h delete mode 100644 src/core/2/cn/codac2_ContractorNode.cpp create mode 100644 src/core/2/cn/codac2_DomainCaster.cpp create mode 100644 src/core/2/cn/codac2_DomainCaster.h delete mode 100644 src/core/2/cn/codac2_DomainNode.cpp create mode 100644 src/core/2/cn/codac2_PropagationSpan.cpp create mode 100644 src/core/2/cn/codac2_PropagationSpan.h create mode 100644 src/core/2/cn/codac2_Var.cpp create mode 100644 src/core/2/contractors/codac2_Ctc.h create mode 100644 src/core/2/contractors/codac2_CtcCN.cpp create mode 100644 src/core/2/contractors/codac2_CtcDeriv.h create mode 100644 src/core/2/contractors/codac2_CtcDist.cpp create mode 100644 src/core/2/contractors/codac2_CtcDist.h create mode 100644 src/core/2/contractors/codac2_CtcInter.cpp create mode 100644 src/core/2/contractors/codac2_CtcNoCross.cpp create mode 100644 src/core/2/contractors/codac2_CtcNoCross.h create mode 100644 src/core/2/contractors/codac2_CtcPolar.cpp create mode 100644 src/core/2/contractors/codac2_CtcPolar.h create mode 100644 src/core/2/contractors/codac2_CtcUnion.h create mode 100644 src/core/2/contractors/codac2_arithmetic_ctc.cpp create mode 100644 src/core/2/contractors/codac2_arithmetic_ctc.h create mode 100644 src/core/2/contractors/codac2_linear_ctc.cpp create mode 100644 src/core/2/contractors/codac2_linear_ctc.h create mode 100644 src/core/2/domains/interval/codac2_IntervalVector.cpp create mode 100644 src/core/2/domains/interval/codac2_IntervalVectorComponent.h create mode 100644 src/core/2/domains/paving/codac2_Paving.cpp create mode 100644 src/core/2/tools/codac2_isbaseof.h create mode 100644 src/core/2/tools/codac2_tuples.h create mode 100644 tests/core/tests_codac2_CtcUnion.cpp create mode 100644 tests/core/tests_codac2_cn.cpp diff --git a/python/src/core/2/cn/codac2_py_Contractor.cpp b/python/src/core/2/cn/codac2_py_Contractor.cpp index bc5d82582..358e3a048 100644 --- a/python/src/core/2/cn/codac2_py_Contractor.cpp +++ b/python/src/core/2/cn/codac2_py_Contractor.cpp @@ -15,7 +15,7 @@ #include #include "codac_type_caster.h" -#include "codac2_Contractor.h" +#include "codac2_Ctc.h" using namespace std; using namespace codac; @@ -26,7 +26,7 @@ using namespace pybind11::literals; void export_Contractor_codac2(py::module& m) { - py::class_ // this is needed to handle shared_ptr with pybind11 > n(m, "ContractorNodeBase", "todo"); @@ -49,5 +49,5 @@ void export_Contractor_codac2(py::module& m) .def("__call__", [](codac2::Contractor1& ctc,IntervalVector_<3>& x) { return ctc(x); }, "todo", py::return_value_policy::reference_internal) - ; + ;*/ } \ No newline at end of file diff --git a/python/src/core/2/cn/codac2_py_ContractorNetwork.cpp b/python/src/core/2/cn/codac2_py_ContractorNetwork.cpp index 5add4022d..497044d75 100644 --- a/python/src/core/2/cn/codac2_py_ContractorNetwork.cpp +++ b/python/src/core/2/cn/codac2_py_ContractorNetwork.cpp @@ -26,7 +26,7 @@ using namespace pybind11::literals; void export_ContractorNetwork_codac2(py::module& m) { - py::class_ cn(m, "ContractorNetwork2", "todo"); + /*py::class_ cn(m, "ContractorNetwork2", "todo"); cn // Definition @@ -41,5 +41,5 @@ void export_ContractorNetwork_codac2(py::module& m) .def("contract", &ContractorNetwork::contract, "todo", "verbose"_a=true) - ; + ;*/ } \ No newline at end of file diff --git a/src/core/2/cn/codac2_Contractor.cpp b/src/core/2/cn/codac2_Contractor.cpp deleted file mode 100644 index 1430208b0..000000000 --- a/src/core/2/cn/codac2_Contractor.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "codac2_Contractor.h" - -using namespace std; - -namespace codac2 -{ - Contractor1::Contractor1() - { - - } - - void Contractor1::contract(IntervalVector_<3>& x) - { - cout << "Calling C1" << endl; - x[0] = Interval(0,1); - x[1] = Interval(0,1); - x[2] = Interval(42,43); - } - - - Contractor2::Contractor2() - { - - } - - void Contractor2::contract(IntervalVector_<2>& x, IntervalVector_<3>& y) - { - cout << "Calling C2" << endl; - x[0] &= y[2]; - y[1] &= Interval(-5,6); - } -} \ No newline at end of file diff --git a/src/core/2/cn/codac2_Contractor.h b/src/core/2/cn/codac2_Contractor.h deleted file mode 100644 index 549e1a078..000000000 --- a/src/core/2/cn/codac2_Contractor.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef __CODAC2_CONTRACTOR__ -#define __CODAC2_CONTRACTOR__ - -#include -#include "codac2_IntervalVector.h" -#include "codac2_ContractorNode.h" - -namespace codac2 -{ - - #define make_available_in_cn() \ - template \ - std::shared_ptr operator()(T&... a) \ - { \ - return std::make_shared::type,T...>>(*this, a...); \ - } \ - - #define make_available_in_cn__templated(template_args) \ - template \ - std::shared_ptr operator()(T&... a) \ - { \ - return std::make_shared>(*this, a...); \ - } \ - - class Contractor - { - public: - - virtual ~Contractor() = default; - }; - - template - class ContractorOnBox : public Contractor - { - public: - - virtual void contract(IntervalVector_& x) = 0; - }; - - class Contractor1 : public Contractor - { - public: - - Contractor1(); - void contract(IntervalVector_<3>& x); - - make_available_in_cn() - }; - - - class Contractor2 : public Contractor - { - public: - - Contractor2(); - void contract(IntervalVector_<2>& x, IntervalVector_<3>& y); - - make_available_in_cn() - }; - -} - -#endif \ No newline at end of file diff --git a/src/core/2/cn/codac2_ContractorNetwork.cpp b/src/core/2/cn/codac2_ContractorNetwork.cpp index b2d67a0c8..85567b179 100644 --- a/src/core/2/cn/codac2_ContractorNetwork.cpp +++ b/src/core/2/cn/codac2_ContractorNetwork.cpp @@ -1,77 +1,140 @@ -#include -#include +/** + * ContractorNetwork class + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2021 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + #include "codac2_ContractorNetwork.h" using namespace std; +using namespace codac2; + +ContractorNetwork::ContractorNetwork() +{ } -namespace codac2 +ContractorNetwork::ContractorNetwork(std::initializer_list> l) { - ContractorNetwork::ContractorNetwork() - { + for(const auto& li : l) + add(li); +} - } +void ContractorNetwork::add(const std::shared_ptr& ctc) +{ + ctc->associate_domains(_v_domains); + _v_ctc.push_back(ctc); + _stack.push_back(ctc); // to be contracted at least once +} - void ContractorNetwork::add(const shared_ptr& ctc) - { - ctc->associate_domains(_v_domains); - _v_ctc.push_back(ctc); - add_ctc_to_stack(ctc); // to be contracted at least once - } +void ContractorNetwork::add(const std::vector>& v_ctc) +{ + for(const auto& ci : v_ctc) + add(ci); +} - void ContractorNetwork::add_ctc_to_stack(const shared_ptr& ctc) - { - if(find(_stack.begin(),_stack.end(),ctc) == _stack.end()) - _stack.push_back(ctc); - } +void ContractorNetwork::merge_into_stack(std::shared_ptr ctc) +{ + std::list> merged_items; + for(auto& c : _stack) + if(c->same_raw_ctcdoms(ctc) && c->is_impacted(ctc->views())) + { + c->extend_views(ctc->views()); + // todo: break? + merged_items.push_back(c); + } + + if(merged_items.empty()) + _stack.push_back(ctc); - void ContractorNetwork::disable_auto_fixpoint(bool disable) + else + for(const auto& merged_i : merged_items) + _stack.splice(_stack.end(), _stack, std::find(_stack.begin(), _stack.end(), merged_i)); +} + +template +char plural(const W& w) +{ + return w.size() > 1 ? 's' : '\0'; +} + +double ContractorNetwork::contract(bool verbose, bool verbose_ctc_calls) +{ + if(verbose) { - _auto_fixpoint = !disable; + std::cout << "Contractor network (" + << _v_ctc.size() << " contractor" << plural(_v_ctc) << ", " + << _v_domains.size() << " domain" << plural(_v_domains) << ")" << std::endl; + std::cout << "Computing, " << _stack.size() << " contractor" << plural(_stack) << " currently in stack..." << std::endl; } - double ContractorNetwork::contract(bool verbose) + clock_t t_start = clock(); + + while(!_stack.empty()) { - if(verbose) + std::shared_ptr ci = _stack.front(); + _stack.pop_front(); + + if(verbose_ctc_calls) + std::cout << "Calling " << ci->to_string() << std::endl; + + auto ci_contracted_views = ci->contract_and_propag(); + ci_contracted_views.remove(nullptr); + ci_contracted_views.remove_if([](const std::shared_ptr& v){ return v->is_empty(); }); + + if(verbose_ctc_calls) { - std::cout << "Contractor network (" << _v_ctc.size() - << " contractors, " << _v_domains.size() << " domains)" << std::endl; - std::cout << "Computing, " << _stack.size() << " contractors currently in stack" << std::endl; + std::cout << " Propagating views ="; + if(ci_contracted_views.empty()) + std::cout << " none."; + else + for(const auto& vi : ci_contracted_views) + std::cout << " " << vi->to_string(); + std::cout << std::endl; } - clock_t t_start = clock(); - - while(!_stack.empty()) + for(const auto& cj : _v_ctc) // could be restricted to ctc of domains of this ctc { - shared_ptr current_ctc = _stack.front(); - _stack.pop_front(); - - auto contracted_doms = current_ctc->call_contract(false); - - for(auto& d : contracted_doms) - for(auto& ci : d->contractors()) - { - auto p_c = ci.lock(); - if(!_auto_fixpoint && current_ctc.get() == p_c.get()) continue; - add_ctc_to_stack(p_c); - } + // All the contractors related to contracted views are added to the stack + if((_force_fixed_point || !ci->same_raw_ctcdoms(cj)) && cj->is_impacted(ci_contracted_views)) + { + auto new_cj = cj->create_viewed_ctc(ci_contracted_views); + if(verbose_ctc_calls) + std::cout << " Creating new contractor node: " << new_cj->to_string() << std::endl; + merge_into_stack(new_cj); + } } - - double elapsed_time = (double)(clock()-t_start)/CLOCKS_PER_SEC; - if(verbose) - std::cout << " Constraint propagation time: " << elapsed_time << "s" << std::endl; - return elapsed_time; - } - - void ContractorNetwork::reset_all_vars() - { - for(auto& d : _v_domains) - if(d->is_var()) - d->reset(); } - void ContractorNetwork::trigger_all_contractors() - { - for(auto& c : _v_ctc) - add_ctc_to_stack(c); - } + double elapsed_time = (double)(clock()-t_start)/CLOCKS_PER_SEC; + if(verbose) + std::cout << "> Constraint propagation time: " << elapsed_time << "s" << std::endl; + return elapsed_time; +} + +void ContractorNetwork::reset_variables() +{ + for(auto& x : _v_domains) + x->reset_if_var(); +} + +void ContractorNetwork::force_fixed_point(bool force) +{ + _force_fixed_point = force; +} + +void ContractorNetwork::get_views_from_cn(std::list>& l) +{ + for(auto& ctc : _v_ctc) + for(auto& ctc_vi : ctc->views()) + if(!ctc_vi->is_view_from_var() && !ctc_vi->is_view_from_const()) + l.push_back(ctc_vi); +} + +void ContractorNetwork::trigger_all_contractors() +{ + for(auto& ctc : _v_ctc) + _stack.push_back(ctc); } \ No newline at end of file diff --git a/src/core/2/cn/codac2_ContractorNetwork.h b/src/core/2/cn/codac2_ContractorNetwork.h index d7a0ab2d6..28103312a 100644 --- a/src/core/2/cn/codac2_ContractorNetwork.h +++ b/src/core/2/cn/codac2_ContractorNetwork.h @@ -1,51 +1,75 @@ +/** + * \file + * ContractorNetwork class + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + #ifndef __CODAC2_CONTRACTORNETWORK__ #define __CODAC2_CONTRACTORNETWORK__ #include #include #include -#include "codac2_DomainNode.h" -#include "codac2_ContractorNode.h" -#include "codac2_Var.h" +#include +#include namespace codac2 { + class CtcCN; + class PropagationSpanBase; + + /** + * \brief Builds a graph of contractors and domains, allowing constraint propagation + * under the form of domains contractions. + */ class ContractorNetwork { public: + /** + * \brief Creates an empty graph. + */ ContractorNetwork(); - void add(const std::shared_ptr& ctc); - void add_ctc_to_stack(const std::shared_ptr& ctc); - void disable_auto_fixpoint(bool disable = true); - double contract(bool verbose = true); - void reset_all_vars(); + /** + * \brief Creates a graph made of a list of contractors nodes. + * The domains nodes are extracted from the contractors nodes and connected to this CN. + * + * \param l a list of pointers to contractors nodes + */ + ContractorNetwork(std::initializer_list> l); - template - void reset_var(const Var *ref, const T& x) - { - for(auto& d : _v_domains) - if(d->raw_ptr() == ref) - { - static_cast&>(*d).get() = x; - return; - } + /** + * \brief Adds a contractor node to the graph. + * The related domains are extracted from the contractor node and connected to this CN. + * + * \param ctc a pointer to the contractor node to be added + */ + void add(const std::shared_ptr& ctc); + void add(const std::vector>& v_ctc); + double contract(bool verbose = true, bool verbose_ctc_calls = false); + void reset_variables(); + void force_fixed_point(bool force = true); + void trigger_all_contractors(); - assert(false && "unable to find variable"); - } + protected: - void trigger_all_contractors(); + void merge_into_stack(std::shared_ptr ctc); - //protected: + friend class CtcCN; + void get_views_from_cn(std::list>& l); std::vector> _v_ctc; std::vector> _v_domains; std::list> _stack; - bool _auto_fixpoint = true; + bool _force_fixed_point = false; }; - } #endif \ No newline at end of file diff --git a/src/core/2/cn/codac2_ContractorNode.cpp b/src/core/2/cn/codac2_ContractorNode.cpp deleted file mode 100644 index 98a0f4928..000000000 --- a/src/core/2/cn/codac2_ContractorNode.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include "codac2_ContractorNode.h" - -using namespace std; - -namespace codac2 -{ - ostream& operator<<(ostream& os, const ContractorNodeBase& d) - { - os << "Contractor: " << d.contractor_class_name() << ", dom=" << d.nb_args() << endl; - return os; - } -} \ No newline at end of file diff --git a/src/core/2/cn/codac2_ContractorNode.h b/src/core/2/cn/codac2_ContractorNode.h index 2d2d379ff..6f5d2d026 100644 --- a/src/core/2/cn/codac2_ContractorNode.h +++ b/src/core/2/cn/codac2_ContractorNode.h @@ -2,90 +2,158 @@ #define __CODAC2_CONTRACTORNODE__ #include -#include #include -#include +#include #include "codac2_DomainNode.h" +#include "codac2_PropagationSpan.h" +#include "codac2_tuples.h" namespace codac2 { - class Contractor; - class ContractorNodeBase; + class DomainNodeBase; class ContractorNodeBase { public: - virtual ~ContractorNodeBase() = default; - virtual size_t nb_args() const = 0; - virtual std::list> call_contract(bool verbose = false) = 0; - virtual Contractor* raw_ptr() const = 0; + ContractorNodeBase() {} + virtual std::list> contract_and_propag() = 0; + virtual bool is_impacted(const std::list>& views) const = 0; + virtual std::shared_ptr create_viewed_ctc(const std::list>& views) = 0; + virtual bool same_raw_ctcdoms(const std::shared_ptr& c) const = 0; + virtual void extend_views(const std::list>& views) = 0; + virtual const std::list>& views() = 0; virtual void associate_domains(std::vector>& cn_domains) = 0; - virtual std::string contractor_class_name() const = 0; - friend std::ostream& operator<<(std::ostream& os, const ContractorNodeBase& d); + virtual std::string to_string() const = 0; }; + template + class DomainNode; + template class ContractorNode : public ContractorNodeBase, - // The following is needed to handle shared_ptr with pybind11: - public std::enable_shared_from_this> + // The following is needed to handle shared_ptr with pybind11: (todo: still valid?) + public std::enable_shared_from_this> { public: - ContractorNode(C& ctc, T&... x) - : _ctc(std::ref(ctc)), - _x(std::make_tuple((std::make_shared: - typename std::remove_reference::type - >>(x)) ...)) + ContractorNode(C& ctc, T&&... x) + : _ctc(ctc), _x(std::make_tuple((std::make_shared>(std::forward(x)))...)), + _views(ctc.get_default_spans(x...)) + { } + + bool is_impacted(const std::list>& views) const { + for(const auto& external_view : views) + for(const auto& internal_view : _views) + if(external_view->intersects(internal_view)) + return true; + return false; + } + void extend_views(const std::list>& views) + { + for(const auto& vout : views) + { + if(vout == nullptr || vout->is_empty()) + continue; + + bool has_been_merged = false; + + for(auto& vin : _views) + if(vin->intersects(vout)) + { + vin->merge(vout); + has_been_merged = true; + break; + } + + if(!has_been_merged) + { + std::cout << "o" << std::endl; + _views.push_back(vout); + std::cout << "pushingback " << vout->to_string() << std::endl; + } + } } - size_t nb_args() const + const std::list>& views() { - return std::tuple_size::value; + return _views; } - Contractor* raw_ptr() const + // must be protected: + ContractorNode(ContractorNode& c, const std::list>& views) + : _ctc(c._ctc), _x(c._x), _views(views) { - return &(_ctc.get()); + } - void process_domain_after_ctc(const std::shared_ptr& d, std::list>& l) + bool same_raw_ctcdoms(const std::shared_ptr& c) const { - if(d->has_been_contrated()) - l.push_back(d); + auto pc = std::dynamic_pointer_cast>(c); + return pc && &pc->_ctc == &_ctc && are_all_members_the_same(_x,pc->_x); + } + + std::shared_ptr create_viewed_ctc(const std::list>& views) + { + std::list> merged_views(_views); + // Merging views + for(auto& v : merged_views) + { + bool has_been_restricted = false; + for(const auto& ev : views) + { + if(v->intersects(ev)) + { + v->contract(ev); + has_been_restricted = true; + break; + } + } + if(!has_been_restricted) + v = nullptr; + } + merged_views.remove(nullptr); + return std::make_shared>(*this, merged_views); } - std::list> call_contract(bool verbose = false) + std::list> contract_and_propag() { - if(verbose) - std::cout << "Calling " << contractor_class_name() << std::endl; - std::list> contracted_doms; + std::list> output_views; std::apply( - [this](auto &&... args) + [this,&output_views](auto &&... args) { - _ctc.get().contract(args->get()...); + output_views = _ctc.contract_and_propag(*args...); }, _x); + return output_views; + } + + std::string to_string() const + { + std::string ctc_name = _ctc.name(); + ctc_name += "("; std::apply( - [this,&contracted_doms](auto &&... args) + [&ctc_name](auto &&... args) { - (process_domain_after_ctc(args,contracted_doms),...); + ((ctc_name += args->to_string() + ","),...); }, _x); - - return contracted_doms; + ctc_name.pop_back(); + ctc_name += ") triggered from one of the views={"; + for(const auto& vi : _views) + ctc_name += vi->to_string() + ","; + ctc_name.pop_back(); + return ctc_name + "}"; } template void associate_domain(std::vector>& cn_domains, std::shared_ptr& d) { for(auto& cn_xi : cn_domains) - if(cn_xi.get() == d.get() || d->raw_ptr() == cn_xi->raw_ptr()) + if(*d == cn_xi) // domains have same origin { d = std::dynamic_pointer_cast(cn_xi); return; @@ -108,18 +176,13 @@ namespace codac2 { (args->add_ctc(this->shared_from_this()),...); }, _x); - } - - std::string contractor_class_name() const - { - return typeid(C).name(); - } - + } protected: - std::reference_wrapper _ctc; + C& _ctc; std::tuple>...> _x; + std::list> _views; }; } diff --git a/src/core/2/cn/codac2_DomainCaster.cpp b/src/core/2/cn/codac2_DomainCaster.cpp new file mode 100644 index 000000000..6f7faff5b --- /dev/null +++ b/src/core/2/cn/codac2_DomainCaster.cpp @@ -0,0 +1,50 @@ +/** + * DomainCaster class + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_DomainCaster.h" + +using namespace std; +using namespace codac2; + + +DomainCaster::DomainCaster(Paving& x) + : _x(x) +{ } + +DomainCaster::operator Paving&() +{ + return _x; +} + +std::shared_ptr DomainCaster::update_and_propag() +{ + double new_volume = _x.volume(); + size_t new_nb_leaves = _x.nb_leaves(); + + if(new_volume != _prev_volume || new_nb_leaves != _prev_nb_leaves) + { + _prev_volume = new_volume; + _prev_nb_leaves = new_nb_leaves; + return std::make_shared>(&_x); + } + + else + return nullptr; +} + +bool DomainCaster::operator==(const DomainCaster& x) const +{ + return &_x == &x._x; +} + +std::string DomainCaster::to_string() const +{ + return _x.name(); +} \ No newline at end of file diff --git a/src/core/2/cn/codac2_DomainCaster.h b/src/core/2/cn/codac2_DomainCaster.h new file mode 100644 index 000000000..4eb9af69a --- /dev/null +++ b/src/core/2/cn/codac2_DomainCaster.h @@ -0,0 +1,259 @@ +/** + * \file + * DomainCaster class + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_DOMAINCASTER__ +#define __CODAC2_DOMAINCASTER__ + +#include +#include +#include +#include +#include +// Includes related to specialization +#include +#include +#include +#include + +namespace codac2 +{ + /** + * \brief Virtual class for handling DomainCaster<> objects + */ + class DomainCasterBase + { + public: + + virtual std::shared_ptr update_and_propag() = 0; + }; + + /*template + struct KK + { + public: + using TT = T; + }; + + template + struct KK> + { + public: + using TT = T; + };*/ + + /** + * \brief Defines a caster for implicitly converting input types ('double', 'Interval', 'Vector') into + * contractible types that can be directly processed by contractors (resp. 'Interval', 'Interval', + * 'IntervalVector'). This facilitates the use of CN and allows more flexibility is the combination of contractors. + * In addition, the caster is responsible for propagation by producing a PropagationSpan. + * + * \tparam InputType type of the input variable that has to be casted into a domain type + */ + template + class DomainCaster : public DomainCasterBase + { + public: + + //using TT = typename KK::type>::TT; + + using OutputType = typename std::remove_reference::type; + // ^ The OutputType is the type that is actually processed by the CN. + // The InputType is the C++ type of the external object involved by the user. + // InputType is relative to the language (it can be 'double', 'Vector', 'Interval') + // while OutputType is a type that can be processed by contractors (resp. 'Interval', + // 'IntervalVector', 'Interval'). + + const bool _is_const_domain = !std::is_base_of::value; + // ^ By default, an object that inherits from Domain is not const. + // For specific cases such as const Interval&, template specialization allows + // to redefine this value. + + /** + * \brief Creates a domain caster from InputType x to an OutputType contractible domain. + * + * \param x input type, also used as a key in the CN, based on its memory adress + */ + DomainCaster(InputType x) // InputType may be a reference + : _x(x), _x_before_ctc(x) + { } + + /** + * \brief Operator allowing the cast from InputType to OutputType + * + * \return the corresponding casted domain, that can be directly used by contractors + */ + operator OutputType&() + { + // In this class, if InputType!=OutputType, we assume that automatic + // cast is possible from InputType to OutputType. + // See template specialization for other cases. + return _x; + } + + /** + * \brief It may be necessary to call for the update of the external domain (that is not + * managed by the CN, and corresponding to InputType for the caster). The update can be + * done based on the value of the OutputType of this caster. The function returns a view + * corresponding to the updated part of the InputType. This propagation span then allows + * further contractions in the CN. + * + * \return a pointer to the new created view + */ + std::shared_ptr update_and_propag() + { + // No explicit update is needed: direct reference has + // been used to contract the domain. + + // Generating the view based on the recent contractness: + auto span = propagspan_from_contraction(_x_before_ctc, _x); + _x_before_ctc = _x; // saved value for future comparisons + return span; + } + + /** + * \brief Tests if this caster and x are related to the same external value. + * + * \param x a pointer to the caster to be tested. + * \return `true` if the two casters casts the same external value. + */ + bool operator==(const DomainCaster& x) const + { + return &_x == &x._x; + } + + /** + * \brief Returns the name of the represented domain in the CN. + * This name is actually related to the external value, that can be + * directly named by the user. + * + * \return the name of the domain. + */ + std::string to_string() const + { + return _x.name(); + } + + protected: + + InputType _x; // may be a reference depending on InputType + // _x represents the actual value managed by the CN during propagations + // _x is also used as a key in the CN, based on its memory adress + OutputType _x_before_ctc; + // _x_before_ctc is a local variable only used to assess the contraction: + // it enables the propagation process via PropagationSpan objects + }; + + #define create_caster(InputType, OutputType_, is_const_fnc, view_fnc, update_fnc, str_fnc) \ + class DomainCaster : public DomainCasterBase \ + { \ + public: \ + \ + using OutputType = OutputType_; \ + const bool _is_const_domain = is_const_fnc; \ + \ + DomainCaster(InputType x) \ + : _x(x) \ + { \ + _y = std::make_shared(_x); \ + _y_before_ctc = std::make_shared(_x); \ + } \ + \ + operator OutputType&() \ + { \ + return *_y; \ + } \ + \ + std::shared_ptr update_and_propag() \ + { \ + auto span = view_fnc; \ + update_fnc; \ + return span; \ + } \ + \ + bool operator==(const DomainCaster& x) const \ + { \ + return &_x == &x._x; \ + } \ + \ + std::string to_string() const \ + { \ + std::ostringstream s; \ + str_fnc; \ + return s.str(); \ + } \ + \ + protected: \ + \ + InputType _x; \ + std::shared_ptr _y = nullptr, _y_before_ctc = nullptr; \ + }; \ + + #define create_caster_for_const_value(InputType_, OutputType_) \ + create_caster(InputType_, OutputType_, \ + true, /* the external value is const */ \ + nullptr, /* the propagation span is null: no propagation for const values */ \ + *_y = *_y_before_ctc, /* the internal domain is updated with a saved value before contraction */ \ + s << _x /* the name of the domain is the value itself, as defined by the user */ \ + ) \ + + // Casters for const values + + template<> + create_caster_for_const_value(int, Interval) + + template<> + create_caster_for_const_value(int&, Interval) + + template<> + create_caster_for_const_value(double, Interval) + + template<> + create_caster_for_const_value(double&, Interval) + + template<> + create_caster_for_const_value(Vector, IntervalVector); + + template<> + create_caster_for_const_value(const Vector&, IntervalVector); + + template<> + create_caster_for_const_value(Interval, Interval) + + template<> + create_caster_for_const_value(const Interval&, Interval); + + template<> + create_caster_for_const_value(const IntervalVector&, IntervalVector); + + // Other cases + + template<> + class DomainCaster : public DomainCasterBase + { + public: + + using OutputType = Paving; + + DomainCaster(Paving& x); + operator Paving&(); + std::shared_ptr update_and_propag(); + bool operator==(const DomainCaster& x) const; + std::string to_string() const; + + protected: + + Paving& _x; + double _prev_volume = 0.; + size_t _prev_nb_leaves = 0.; + }; +} + +#endif \ No newline at end of file diff --git a/src/core/2/cn/codac2_DomainNode.cpp b/src/core/2/cn/codac2_DomainNode.cpp deleted file mode 100644 index adac0819a..000000000 --- a/src/core/2/cn/codac2_DomainNode.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "codac2_DomainNode.h" - -using namespace std; - -namespace codac2 -{ - ostream& operator<<(ostream& os, const DomainNodeBase& d) - { - os << "Domain: " << d.domain_class_name() << ", ctc=" << d.contractors().size() << endl; - return os; - } -} \ No newline at end of file diff --git a/src/core/2/cn/codac2_DomainNode.h b/src/core/2/cn/codac2_DomainNode.h index a9c38f25c..c26d6c160 100644 --- a/src/core/2/cn/codac2_DomainNode.h +++ b/src/core/2/cn/codac2_DomainNode.h @@ -1,85 +1,61 @@ #ifndef __CODAC2_DOMAINNODE__ #define __CODAC2_DOMAINNODE__ -#include -#include +#include #include -#include -#include "codac2_Domain.h" +#include + +#include "codac2_ContractorNode.h" +#include "codac2_PropagationSpan.h" #include "codac2_Var.h" +#include "codac2_isbaseof.h" namespace codac2 { - class Contractor; class ContractorNodeBase; class DomainNodeBase { public: + DomainNodeBase() {} virtual ~DomainNodeBase() = default; - virtual void print() const = 0; - virtual const Domain* raw_ptr() const = 0; - virtual bool has_been_contrated() = 0; virtual const std::vector>& contractors() const = 0; - virtual void add_ctc(const std::shared_ptr& ctc) = 0; - virtual std::string domain_class_name() const = 0; - virtual void reset() = 0; + virtual void reset_if_var() = 0; + virtual bool operator==(const std::shared_ptr& x) const = 0; + virtual std::string to_string() const = 0; virtual bool is_var() const = 0; - - friend std::ostream& operator<<(std::ostream& os, const DomainNodeBase& d); }; - template - class DomainNode : public DomainNodeBase - { - using T = typename std::remove_const::type; - - public: - constexpr static bool _is_var = std::is_base_of::value; + template + class PropagationSpan; - std::reference_wrapper make_ref(T_& x) - { - if constexpr (std::is_const::value) - { - _local_dom = std::make_shared(x); - return std::ref(*_local_dom); - } - else - return std::ref(x); - } + template + class DomainCaster; - explicit DomainNode(T_& x) - : _x(make_ref(x)), _volume(x.dom_volume()) - { - if constexpr (std::is_const::value) - _raw_ptr = &x; - else - _raw_ptr = &(_x.get()); - } + template + class DomainNode : public DomainNodeBase + { + public: - T& get() - { - return _x.get(); - } + DomainNode(T&& x) + : _dom_cast(std::forward(x)) + { } - void print() const + operator typename DomainCaster::OutputType&() { - std::cout << _x.get() << std::flush; + return _dom_cast.operator typename DomainCaster::OutputType&(); } - const Domain* raw_ptr() const + void add_ctc(const std::shared_ptr& ctc) { - return _raw_ptr; + _v_ctc.push_back(ctc); } - bool has_been_contrated() + std::shared_ptr update_and_propag() { - DomainVolume new_vol = _x.get().dom_volume(); - bool contracted = new_vol != _volume; - _volume = new_vol; - return contracted; + return _dom_cast.update_and_propag(); } const std::vector>& contractors() const @@ -87,40 +63,33 @@ namespace codac2 return _v_ctc; } - void add_ctc(const std::shared_ptr& ctc) - { - _v_ctc.push_back(ctc); - } - - std::string domain_class_name() const + bool operator==(const std::shared_ptr& x) const { - return typeid(T).name(); + if(typeid(DomainNode) != typeid(*x)) + return false; + return _dom_cast == std::dynamic_pointer_cast>(x)->_dom_cast; } - void reset() + /* todo C++20: constexpr*/ bool is_var() const { - if constexpr(_is_var) - _x.get().reset(); + return is_base_of_any::type>::value; } - void reset(const T& x) + void reset_if_var() { - if constexpr(_is_var) - _x.get().reset(x); + if /* todo C++20: constexpr and use is_var*/constexpr(is_base_of_any::type>::value) + _dom_cast.operator typename DomainCaster::OutputType&().reset_to_default_value(); } - constexpr bool is_var() const + std::string to_string() const { - return _is_var; + return _dom_cast.to_string(); } protected: - std::shared_ptr _local_dom = nullptr; - std::reference_wrapper _x; - DomainVolume _volume; - std::vector> _v_ctc; // is dynamic - const Domain *_raw_ptr; // used as a key + DomainCaster _dom_cast; + std::vector> _v_ctc; }; } diff --git a/src/core/2/cn/codac2_PropagationSpan.cpp b/src/core/2/cn/codac2_PropagationSpan.cpp new file mode 100644 index 000000000..ff4ea5def --- /dev/null +++ b/src/core/2/cn/codac2_PropagationSpan.cpp @@ -0,0 +1,227 @@ +/** + * PropagationSpan class + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2021 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_PropagationSpan.h" + +using namespace std; +using namespace codac2; + +//template<> +//bool PropagationSpan::intersects(const std::shared_ptr& view) const +//{std::cout << "ici" << std::endl; +// return false; +//} + + +// ================================================================================================== +// Specialization PropagationSpan + +PropagationSpan::PropagationSpan(const IntervalVector* x) + : _x(x), _indices(x->size()) +{ + std::iota(_indices.begin(), _indices.end(), 0); +} + +PropagationSpan::PropagationSpan(const IntervalVector* x, const std::vector& indices) + : _x(x), _indices(indices) +{ + +} + +bool PropagationSpan::is_empty() const +{ + return _indices.empty(); +} + +bool PropagationSpan::is_non_contractible() const +{ + return _x->volume() == 0.; +} + +bool PropagationSpan::intersects(const std::shared_ptr& view) const +{ + auto view_cast_iv = std::dynamic_pointer_cast>(view); + if(view_cast_iv) + { + if(view_cast_iv->_x == _x) + return true; + + for(const auto& i : _indices) + for(const auto& i_view : view_cast_iv->_indices) + { + if(&(*_x)[i] == &(*view_cast_iv->_x)[i_view]) + return true; + if(i_view > i) + break; // i is not in the ordered vector view_cast->_indices + } + } + + // todo: is this working? + auto view_cast_i = std::dynamic_pointer_cast>(view); + if(view_cast_i) + { + for(size_t i = 0 ; i < _x->size() ; i++) + if(&(*_x)[i] == view_cast_i->_x) + return true; + } + + return false; +} + +void PropagationSpan::contract(const std::shared_ptr& view) +{ + auto view_cast = std::dynamic_pointer_cast>(view); + assert(view_cast && "fail to pointer cast PropagationSpanBase into PropagationSpan"); + assert(view_cast->_x == _x && "views are not related to the same domain"); + + std::vector indices; + for(const auto& di : _indices) + for(const auto& xdi : view_cast->_indices) + if(di == xdi) + { + indices.push_back(di); + break; + } + _indices = indices; +} + +void PropagationSpan::merge(const std::shared_ptr& view) +{ + auto view_cast = std::dynamic_pointer_cast>(view); + assert(view_cast && "fail to pointer cast PropagationSpanBase into PropagationSpan"); + assert(view_cast->_x == _x && "views are not related to the same domain"); + + std::vector merged_indices; + std::set_union(_indices.cbegin(), _indices.cend(), + view_cast->_indices.cbegin(), view_cast->_indices.cend(), + std::back_inserter(merged_indices)); + _indices = merged_indices; +} + +bool PropagationSpan::is_view_from_const() const +{ + return false; +} + +bool PropagationSpan::is_view_from_var() const +{ + return false; +} + +std::string PropagationSpan::to_string() const +{ + string str = _x->name() + "["; + for(const auto& i : _indices) + str += std::to_string(i) + ","; + str.pop_back(); + return str + "]"; +} + + +// ================================================================================================== +// Specialization PropagationSpan + +/*PropagationSpan::PropagationSpan(const IntervalVectorComponent& x) + : _x(&x._x), _indices({x._i}) +{ + +} + +bool PropagationSpan::is_empty() const +{ + return _indices.empty(); +} + +bool PropagationSpan::is_non_contractible() const +{ + for(const auto& i : _indices) + if((*_x)[i].volume() != 0.) + return false; + return true; +} + +bool PropagationSpan::intersects(const std::shared_ptr& view) const +{ + auto view_cast = std::dynamic_pointer_cast>(view); + if(!view_cast || view_cast->_x != _x) + return false; + + for(const auto& i : _indices) + for(const auto& i_view : view_cast->_indices) + { + if(i == i_view) + return true; + if(i_view > i) + break; // i is not in the ordered vector view_cast->_indices + } + return false; +} + +void PropagationSpan::contract(const std::shared_ptr& view) +{ + auto view_cast = std::dynamic_pointer_cast>(view); + assert(view_cast && "fail to pointer cast PropagationSpanBase into PropagationSpan"); + assert(view_cast->_x == _x && "views are not related to the same domain"); + + std::vector indices; + for(const auto& di : _indices) + for(const auto& xdi : view_cast->_indices) + if(di == xdi) + { + indices.push_back(di); + break; + } + _indices = indices; +} + +void PropagationSpan::merge(const std::shared_ptr& view) +{ + auto view_cast = std::dynamic_pointer_cast>(view); + assert(view_cast && "fail to pointer cast PropagationSpanBase into PropagationSpan"); + assert(view_cast->_x == _x && "views are not related to the same domain"); + + std::vector merged_indices; + std::set_union(_indices.cbegin(), _indices.cend(), + view_cast->_indices.cbegin(), view_cast->_indices.cend(), + std::back_inserter(merged_indices)); + _indices = merged_indices; +} + +bool PropagationSpan::is_view_from_const() const +{ + return false; +} + +bool PropagationSpan::is_view_from_var() const +{ + return false; +} + +std::string PropagationSpan::to_string() const +{ + string str = _x->name() + "["; + for(const auto& i : _indices) + str += std::to_string(i) + ","; + str.pop_back(); + return str + "]"; +}*/ +/* +template<> +std::shared_ptr propagspan_from_contraction(IntervalVector_<-1>& bef, IntervalVector_<-1>& aft) +{ + cout << "HERE" << endl; + assert(bef.size() == aft.size()); + std::vector indices; + for(size_t i = 0 ; i < bef.size() ; i++) + if(bef[i] != aft[i]) + indices.push_back(i); + auto ptr = std::make_shared>(&aft,indices); + return ptr; +}*/ \ No newline at end of file diff --git a/src/core/2/cn/codac2_PropagationSpan.h b/src/core/2/cn/codac2_PropagationSpan.h new file mode 100644 index 000000000..d0a2ae7e1 --- /dev/null +++ b/src/core/2/cn/codac2_PropagationSpan.h @@ -0,0 +1,243 @@ +#ifndef __CODAC2_DOMAINVIEW__ +#define __CODAC2_DOMAINVIEW__ + +#include +#include "codac2_Tube.h" +#include "codac2_Var.h" +#include "codac2_isbaseof.h" + +namespace codac2 +{ + class PropagationSpanBase + { + public: + + virtual ~PropagationSpanBase() = default; + virtual bool is_empty() const = 0; + virtual bool intersects(const std::shared_ptr& view) const = 0; + virtual void contract(const std::shared_ptr& view) = 0; + virtual void merge(const std::shared_ptr& view) = 0; + virtual bool cannot_propagate() const = 0; + virtual bool is_view_from_var() const = 0; + virtual bool is_view_from_const() const = 0; + virtual std::string to_string() const + { + return "?"; + } + }; + + template + class PropagationSpan : public PropagationSpanBase + { + public: + + const bool _is_const = !std::is_base_of::type>::value; + const bool _is_var = is_base_of_any::type>::value; + + PropagationSpan(const typename std::remove_reference::type* x = nullptr) + : _x(x) + { } + + bool is_empty() const + { + return !_x; + } + + bool is_non_contractible() const + { + if constexpr(std::is_same::value || std::is_same::value) + return true; + if constexpr(std::is_same::value || std::is_same::value) + return _x->volume() == 0.; + return false; // for large domains, avoiding to compute volume + } + + template + PropagationSpan operator&([[maybe_unused]] const PropagationSpan& y) const + { + return PropagationSpan(); + } + + bool intersects(const std::shared_ptr& view) const + { + auto view_cast = std::dynamic_pointer_cast>(view); + return view_cast && (view_cast->_x == _x); + } + + void contract([[maybe_unused]] const std::shared_ptr& view) + { + assert(std::dynamic_pointer_cast>(view) && "cannot contract views from different domains"); + // Nothing to do + } + + void merge([[maybe_unused]] const std::shared_ptr& view) + { + assert(std::dynamic_pointer_cast>(view) && "cannot merge views from different domains"); + // Nothing to do + } + + bool cannot_propagate() const + { + return is_view_from_const() || is_non_contractible(); + } + + bool is_view_from_const() const + { + return _is_const; + } + + bool is_view_from_var() const + { + return _is_var; + } + + std::string to_string() const + { + if(_x) + { + if constexpr(std::is_base_of::value) + { + assert(_x); + if(_x!=nullptr)return _x->name(); + else return "e"; + } + else return "[]"; + //else // could be list + //{ + // std::ostringstream s; + // s << *_x; + // return s.str(); + //} + } + else return "[]"; + } + + //protected: + + const typename std::remove_reference::type* _x = nullptr; + }; + + //template + //std::shared_ptr propagspan_from_contraction(IntervalVectorComponent* bef, T* aft) // bef should be const + //{ + // if(*bef != *aft) + // return std::make_shared>(aft); + // return std::make_shared>(); + //} + + template<> + class PropagationSpan : public PropagationSpanBase + { + public: + + PropagationSpan(const IntervalVector* x); + PropagationSpan(const IntervalVector* x, const std::vector& indices); + bool is_empty() const; + bool is_non_contractible() const; + + bool cannot_propagate() const + { + return is_view_from_const() || is_non_contractible(); + } + + template + PropagationSpan operator&(const PropagationSpan& y) const + { + return PropagationSpan(); + } + + bool intersects(const std::shared_ptr& view) const; + void contract(const std::shared_ptr& view); + void merge(const std::shared_ptr& view); + bool is_view_from_const() const; + bool is_view_from_var() const; + std::string to_string() const; + + //protected: + + const IntervalVector* _x = nullptr; + std::vector _indices; + }; + + template<> + inline bool PropagationSpan::intersects(const std::shared_ptr& view) const + { + auto view_cast_i = std::dynamic_pointer_cast>(view); + if(view_cast_i && view_cast_i->_x == _x) + return true; + + auto view_cast_iv = std::dynamic_pointer_cast>(view); + if(view_cast_iv) + for(const auto& i_view : view_cast_iv->_indices) + if(_x == &(*view_cast_iv->_x)[i_view]) + return true; + + return false; + } + + template + static std::shared_ptr propagspan_from_contraction(Q& bef, Q& aft) // bef should be const + { + if /* todo C++20: constexpr and use is_var*/constexpr(is_base_of_any::type>::value) + return propagspan_from_contraction_var(bef, aft); + + if(bef != aft) + return std::make_shared>(&aft); + return nullptr; // sure? + } + + template + std::shared_ptr propagspan_from_contraction_var(Var& bef, Var& aft) + { + return propagspan_from_contraction(static_cast(bef), static_cast(aft)); + } + + template<> + std::shared_ptr propagspan_from_contraction(IntervalVector& bef, IntervalVector& aft) + { + assert(bef.size() == aft.size()); + std::vector indices; + for(size_t i = 0 ; i < bef.size() ; i++) + if(bef[i] != aft[i]) + indices.push_back(i); + if(!indices.empty()) + return std::make_shared>(&aft,indices); + else + return nullptr; + } + + /*template<> + class PropagationSpan : public PropagationSpanBase + { + public: + + PropagationSpan(const IntervalVectorComponent& x); + bool is_empty() const; + bool is_non_contractible() const; + + bool cannot_propagate() const + { + return is_view_from_const() || is_non_contractible(); + } + + template + PropagationSpan operator&(const PropagationSpan& y) const + { + return PropagationSpan(); + } + + bool intersects(const std::shared_ptr& view) const; + void contract(const std::shared_ptr& view); + void merge(const std::shared_ptr& view); + bool is_view_from_const() const; + bool is_view_from_var() const; + std::string to_string() const; + + //protected: + + const IntervalVector* _x = nullptr; + std::vector _indices; + };*/ +} + +#endif \ No newline at end of file diff --git a/src/core/2/cn/codac2_Var.cpp b/src/core/2/cn/codac2_Var.cpp new file mode 100644 index 000000000..effd2edf8 --- /dev/null +++ b/src/core/2/cn/codac2_Var.cpp @@ -0,0 +1,19 @@ +/** + * Var class + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2021 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_Var.h" + +using namespace std; +using namespace codac2; + +VarBase::VarBase() +{ + +} \ No newline at end of file diff --git a/src/core/2/cn/codac2_Var.h b/src/core/2/cn/codac2_Var.h index ec608906d..f9d69f858 100644 --- a/src/core/2/cn/codac2_Var.h +++ b/src/core/2/cn/codac2_Var.h @@ -1,51 +1,91 @@ #ifndef __CODAC2_VAR__ #define __CODAC2_VAR__ -#include -#include -#include -#include -#include "codac2_Domain.h" +#include +#include +#include namespace codac2 { class VarBase { public: - + + VarBase(); virtual ~VarBase() = default; - VarBase& operator=(const VarBase& x) = delete; }; template - class Var : public T, public VarBase + class Var_ : public T, public VarBase { public: - - Var() - { - } - - Var(const T& initial_value) - : _initial_value(initial_value) - { + Var_(T&& x) : T(x), _reset_value(std::forward(x)) + { } + Var_& operator=(const Var_& v) + { + // This method may be used for DomainCaster + T::operator=(v); + // _reset_var is not updated + return *this; } - void reset() + void set_value(const T& v) { - this->T::operator=(_initial_value); + T::operator=(v); } - void reset(const T& x) + void reset_to_default_value() { - this->T::operator=(x); + T::operator=(_reset_value); } protected: - T _initial_value; + const T _reset_value; + }; + + template + class Var : public Var_ + { + public: + + Var() : Var_(T()) + { } + + template + Var(const Args&... x) : Var_(T(x...)) + { } + }; + + // Some template specializations are performed for specific arguments that cannot be deduced, + // such as initializer_lists. + + template<> + class Var : public Var_ + { + public: + + Var(std::initializer_list l) : Var_(IntervalVector(l)) + { } + + template + Var(const Args&... x) : Var_(IntervalVector(x...)) + { } + }; + + template<> + class Var : public Var_ + { + public: + + Var(std::initializer_list> l) : Var_(IntervalMatrix(l)) + { } + + template + Var(const Args&... x) : Var_(IntervalMatrix(x...)) + { } }; } diff --git a/src/core/2/contractors/codac2_Ctc.h b/src/core/2/contractors/codac2_Ctc.h new file mode 100644 index 000000000..7c42a3dea --- /dev/null +++ b/src/core/2/contractors/codac2_Ctc.h @@ -0,0 +1,204 @@ +/** + * \file + * Ctc class + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_CTC__ +#define __CODAC2_CTC__ + +#include +#include +#include +#include + +namespace codac2 +{ + /** + * \enum TimePropag + * \brief Specifies the temporal propagation way (forward or backward in time) + */ + enum class TimePropag + { + FORWARD = 0x01, ///< forward in time (from \f$t^-\f$ to \f$t^+\f$) + BACKWARD = 0x02 ///< backward in time (from \f$t^+\f$ to \f$t^-\f$) + }; + + /** + * \brief Allows tests on combinations of propagation ways + * + * Used for tests such as `if(time_propag & TimePropag::FORWARD) { ... }` + * + * \param a first TimePropag operand + * \param b second TimePropag operand + * \return intersection of propagation ways + */ + inline int operator&(TimePropag a, TimePropag b) + { return static_cast(static_cast(a) & static_cast(b)); } + + /** + * \brief Allows a combination of propagation ways + * + * \note For instance: `FORWARD | BACKWARD` + * + * \param a first TimePropag operand + * \param b second TimePropag operand + * \return union of propagation ways, such as `FORWARD | BACKWARD` + */ + inline TimePropag operator|(TimePropag a, TimePropag b) + { return static_cast(static_cast(a) | static_cast(b)); } + + /** + * \brief Base class for contractors + * + * The class allows to name the contractors objects for graphical/debugging purposes. + */ + class Ctc + { + public: + + std::string name() const + { + return _name.empty() ? "C?" : _name; + } + + void set_name(const std::string& name) const + { + _name = name; + } + + protected: + + mutable std::string _name; + }; + + class BoxCtc : public Ctc + { + public: + + virtual void contract(IntervalVector& x) = 0; + }; + + // The following functions allow to use the contractors into CNs. + // They must be defined in each derived class for this purpose. + + /** + * \brief Returns a CN node handling the current Ctc object related to the specified domains. + * + * \param x the contractor domains as specified by the user + * \return a pointer to a ContractorNode + */ + #define make_available_to_cn___call_operator() \ + \ + template \ + auto operator()(T&&... x) \ + { \ + return std::make_shared::type,T...>>(*this, std::forward(x)...); \ + } \ + + /** + * \brief Returns the default propagation spans for this contractor, assuming a maximal contraction effect. + * + * This function is used to evaluate if this contractor is impacted by a given propagation effect, + * by comparing its default spans to those resulting from a former contraction. + * + * \param x the contractor domains as specified by the user + * \return a list of domains potentially related to this contractor + */ + #define make_available_to_cn___get_default_spans() \ + \ + template \ + auto create_span_var(Var& x) \ + { \ + return create_span(static_cast(x)); \ + } \ + \ + template \ + auto create_span(T& x) \ + { \ + if constexpr(is_base_of_any::type>::value) \ + return create_span_var(x); \ + else \ + return std::make_shared::type>>(&x); \ + } \ + \ + template \ + auto get_default_spans(T&... x) \ + { \ + std::list> spans; \ + /* Each domain involved in the "contract()" function of the Ctc class are potentially responsible for propagations. */ \ + (spans.push_back(create_span(x)), ...); \ + spans.remove_if([](const std::shared_ptr& v) { return !v || v->cannot_propagate(); }); \ + return spans; \ + } \ + + /** + * \brief Performs the contraction (inside the CN process) and returns the spans allowing propagation. + * + * \param x the contractor domains after automatic cast (see DomainCaster) + * \return a list of spans representing parts of domains that have been contracted + */ + #define make_available_to_cn___contract_and_propag() \ + \ + template \ + auto contract_and_propag(T&&... x) \ + { \ + contract(x...); /* actual mandatory function 'contract(...) of the Ctc object */ \ + std::list> propag_spans; \ + (propag_spans.push_back(x.update_and_propag()), ...); \ + propag_spans.remove_if([](const std::shared_ptr& v) { return !v || v->cannot_propagate(); }); \ + return propag_spans; \ + } \ + + /** + * \brief Allows to vectorize a scalar contractor to a list of vector domains. + * + * \param x the contractor domains after automatic cast (see DomainCaster) + * \return a list of spans representing parts of domains that have been contracted + */ + // not working #define make_available_to_cn___vect() \ + // not working \ + // not working template \ + // not working auto vect(T&&... x) \ + // not working { \ + // not working using CtcClass = typename std::remove_reference::type; \ + // not working size_t n = [](const auto& first, const auto& ...) -> auto { return first.size(); }(x...); \ + // not working std::vector::type::VECTOR_ITEM...>>> v_contractors(n); \ + // not working for(size_t i = 0 ; i < n ; i++) \ + // not working v_contractors[i] = std::make_shared::type::VECTOR_ITEM...>>( \ + // not working *this, std::forward::type::VECTOR_ITEM>(x[i])...); \ + // not working return v_contractors; \ + // not working } \ + + #define make_available_to_cn() \ + make_available_to_cn___call_operator() \ + make_available_to_cn___get_default_spans() \ + make_available_to_cn___contract_and_propag() + + + // The following function allows to use the extand some contractors on slices, to tubes. + // It must be defined in each derived class for this purpose. + + #define make_available_to_tubes() \ + template \ + void contract_fwdbwd(TimePropag t_propa, Tube&... x) \ + { \ + auto tdomain = std::get<0>(std::make_tuple(x...)).tdomain(); \ + \ + if(t_propa & TimePropag::FORWARD) /* Computations related to forward propagation in time */ \ + for(const auto& st : tdomain->tslices()) \ + contract((*std::static_pointer_cast>(st.slices().at(&x)))...); \ + \ + if(t_propa & TimePropag::BACKWARD) /* Computations related to backward propagation in time */ \ + for(auto it = tdomain->tslices().rbegin() ; it != tdomain->tslices().rend() ; ++it) \ + contract((*std::static_pointer_cast>(it->slices().at(&x)))...); \ + } \ + +} + +#endif \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcCN.cpp b/src/core/2/contractors/codac2_CtcCN.cpp new file mode 100644 index 000000000..4009a278a --- /dev/null +++ b/src/core/2/contractors/codac2_CtcCN.cpp @@ -0,0 +1,30 @@ +/** + * CtcCN class + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2021 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_CtcCN.h" +#include "codac2_Var.h" + +using namespace std; +using namespace codac2; + +CtcCN::CtcCN(ContractorNetwork& cn, Var& var) + : _cn(cn), _ref_var(&var) +{ + +} + +void CtcCN::contract(IntervalVector& x) +{ + _cn.reset_variables(); + _ref_var->set_value(x); + _cn.trigger_all_contractors(); + _cn.contract(false, false); + x = *_ref_var; +} \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcCN.h b/src/core/2/contractors/codac2_CtcCN.h index d1f1947a0..72aeeb8bc 100644 --- a/src/core/2/contractors/codac2_CtcCN.h +++ b/src/core/2/contractors/codac2_CtcCN.h @@ -9,40 +9,58 @@ * the GNU Lesser General Public License (LGPL). */ -#ifndef __CODAC2_CTCCN_H__ -#define __CODAC2_CTCCN_H__ +#ifndef __CODAC2_CTCCN__ +#define __CODAC2_CTCCN__ -#include "codac2_Contractor.h" +#include +#include +#include "codac2_Ctc.h" #include "codac2_ContractorNetwork.h" +//#include "codac2_PropagationSpan.h" namespace codac2 { - template - class CtcCN : public ContractorOnBox + //class ContractorNetwork; + + class CtcCN : public Ctc { public: - CtcCN(ContractorNetwork& cn, Var>& var) + CtcCN(ContractorNetwork& cn, Var& var); + void contract(IntervalVector& x); + + /*CtcCN(ContractorNetwork& cn, Var& var) : _cn(cn), _ref_var(&var) { } - void contract(IntervalVector_& x) + void contract(IntervalVector& x) { - _cn.reset_all_vars(); - _cn.reset_var(_ref_var,x); + _cn.reset_variables(); + *_ref_var = x; _cn.trigger_all_contractors(); - _cn.contract(false); + _cn.contract(false,false); x = *_ref_var; + }*/ + + template + std::list> get_default_spans(T&... x) + { + std::list> views; + (views.push_back(std::make_shared::type>>(&x)), ...); + _cn.get_views_from_cn(views); + views.remove_if([](const std::shared_ptr& v) { return !v || v->cannot_propagate(); }); + return views; } - make_available_in_cn__templated(CtcCN) + make_available_to_cn___call_operator() + make_available_to_cn___contract_and_propag() protected: ContractorNetwork& _cn; - const Var>* _ref_var; + Var* _ref_var; }; } diff --git a/src/core/2/contractors/codac2_CtcDeriv.h b/src/core/2/contractors/codac2_CtcDeriv.h new file mode 100644 index 000000000..8cc0dd8fc --- /dev/null +++ b/src/core/2/contractors/codac2_CtcDeriv.h @@ -0,0 +1,61 @@ +/** + * \file + * + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou + * \copyright Copyright 2023 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_CTCDERIV_H__ +#define __CODAC2_CTCDERIV_H__ + +#include "codac2_Ctc.h" +#include "codac2_Interval.h" +#include "codac_predef_contractors.h" + +namespace codac2 +{ + class CtcDeriv : public Ctc + { + public: + + CtcDeriv() + { } + + void contract(Slice& x, const Slice& v) + { + if(x.is_gate()) // the slice may be on a degenerated temporal domain, i.e. a gate + return; + + codac::Slice x_codac1(x.t0_tf(), x.codomain()); + x_codac1.set_input_gate(x.input_gate()); + x_codac1.set_output_gate(x.output_gate()); + + codac::Slice v_codac1(v.t0_tf(), v.codomain()); + v_codac1.set_input_gate(v.input_gate()); + v_codac1.set_output_gate(v.output_gate()); + + codac::ctc::deriv.contract(x_codac1, v_codac1); + x.set(x_codac1.codomain()); + + if(x.prev_slice_ptr() && x.prev_slice_ptr()->is_gate()) + x.prev_slice_ptr()->set(x_codac1.input_gate()); + if(x.next_slice_ptr() && x.next_slice_ptr()->is_gate()) + x.next_slice_ptr()->set(x_codac1.output_gate()); + } + + make_available_to_tubes(); + + void contract(Tube& x, Tube& v, TimePropag t_propa = TimePropag::FORWARD | TimePropag::BACKWARD) + { + contract_fwdbwd(t_propa, x, v); + } + + make_available_to_cn(); + }; +} + +#endif \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcDiffInclusion.h b/src/core/2/contractors/codac2_CtcDiffInclusion.h index 06f266aa3..21d0d4b33 100644 --- a/src/core/2/contractors/codac2_CtcDiffInclusion.h +++ b/src/core/2/contractors/codac2_CtcDiffInclusion.h @@ -20,7 +20,7 @@ namespace codac2 { using codac::TFunction; - using codac::TimePropag; + //using codac::TimePropag; /** * \class CtcDiffInclusion diff --git a/src/core/2/contractors/codac2_CtcDist.cpp b/src/core/2/contractors/codac2_CtcDist.cpp new file mode 100644 index 000000000..6b6777363 --- /dev/null +++ b/src/core/2/contractors/codac2_CtcDist.cpp @@ -0,0 +1,55 @@ +/** + * CtcDist class + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2021 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_CtcDist.h" + +using namespace std; +using namespace codac2; + +CtcDist::CtcDist() +{ } + +void CtcDist::contract(IntervalVector& x) +{ + assert(x.size() == 5); + contract(x[0], x[1], x[2], x[3], x[4]); +} + +void CtcDist::contract(IntervalVector& a, IntervalVector& b, Interval& d) +{ + assert(a.size() == 2 && b.size() == 2); + contract(a[0], a[1], b[0], b[1], d); +} + +void CtcDist::contract(Interval& ax, Interval& ay, Interval& bx, Interval& by, Interval& d) +{ + // Forward + Interval i1 = -bx; + Interval i2 = ax + i1; + Interval i3 = sqr(i2); + Interval i4 = -by; + Interval i5 = ay + i4; + Interval i6 = sqr(i5); + Interval i7 = i3 + i6; + d &= sqrt(i7); + + // Backward + i7 &= sqr(d); + i3 &= i7 - i6; + i6 &= i7 - i3; + bwd_sqr(i6, i5); + ay &= i5 - i4; + i4 &= i5 - ay; + by &= -i4; + bwd_sqr(i3, i2); + ax &= i2 - i1; + i1 &= i2 - ax; + bx &= -i1; +} \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcDist.h b/src/core/2/contractors/codac2_CtcDist.h new file mode 100644 index 000000000..dcafaedd6 --- /dev/null +++ b/src/core/2/contractors/codac2_CtcDist.h @@ -0,0 +1,37 @@ +/** + * \file + * + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2022 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_CTCDIST__ +#define __CODAC2_CTCDIST__ + +#include "codac2_Ctc.h" +#include "codac2_Interval.h" +#include "codac2_IntervalVector.h" + +namespace codac2 +{ + /** + * \class CtcDist + */ + class CtcDist : public Ctc + { + public: + + CtcDist(); + void contract(IntervalVector& x); + void contract(IntervalVector& a, IntervalVector& b, Interval& d); + void contract(Interval& ax, Interval& ay, Interval& bx, Interval& by, Interval& d); + + make_available_to_cn() + }; +} + +#endif \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcInter.cpp b/src/core/2/contractors/codac2_CtcInter.cpp new file mode 100644 index 000000000..e5caf9523 --- /dev/null +++ b/src/core/2/contractors/codac2_CtcInter.cpp @@ -0,0 +1,25 @@ +/** + * CtcInter class + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2021 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_CtcInter.h" + +using namespace std; +using namespace codac2; + +/*CtcInter::CtcInter(Paving& x) + : _x(x) +{ + +} + +void CtcInter::contract(IntervalVector& y) +{ + _x.contract(y); +}*/ \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcInter.h b/src/core/2/contractors/codac2_CtcInter.h index 0fec6b43b..27c37503e 100644 --- a/src/core/2/contractors/codac2_CtcInter.h +++ b/src/core/2/contractors/codac2_CtcInter.h @@ -12,32 +12,44 @@ #ifndef __CODAC2_CTCINTER_H__ #define __CODAC2_CTCINTER_H__ -#include "codac2_Contractor.h" +#include "codac2_Ctc.h" +#include "codac2_Paving.h" +#include "codac2_IntervalVector.h" namespace codac2 { - template - class CtcInter : public Contractor + template + class CtcInter : public Ctc { public: - CtcInter() + CtcInter(Paving_& x) + : _x(x) { } - void contract(Paving& x, IntervalVector_& y) + void contract(IntervalVector_& y) { - auto y_ = y; - y.set_empty(); - for(const auto& l : x.leaves()) - y |= y_ & l.lock()->box(); + _x.contract(y); } - make_available_in_cn__templated(CtcInter) + template + std::list> get_default_spans(T&... x) + { + std::list> views; + (views.push_back(std::make_shared::type>>(&x)), ...); + views.push_back(std::make_shared>>(&_x)); + views.remove_if([](const std::shared_ptr& v) { return !v || v->cannot_propagate(); }); + return views; + } + + make_available_to_cn___call_operator() + make_available_to_cn___contract_and_propag() protected: + Paving_& _x; // todo: const }; } diff --git a/src/core/2/contractors/codac2_CtcNoCross.cpp b/src/core/2/contractors/codac2_CtcNoCross.cpp new file mode 100644 index 000000000..d9d39c958 --- /dev/null +++ b/src/core/2/contractors/codac2_CtcNoCross.cpp @@ -0,0 +1,44 @@ +/** + * CtcNoCross class + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_CtcNoCross.h" +#include "codac2_arithmetic_ctc.h" +#include "codac2_DomainCaster.h" + +using namespace std; +using namespace codac2; + +CtcNoCross::CtcNoCross(const IntervalVector& w1, const IntervalVector& w2, const IntervalVector& m) : + _w1(w1), _w2(w2), _m(m), + t(2), ab(2), mt(2), am(2), at(2), ta(2), tb(2), + _ctc_cn(_cn,t) +{ + //_cn.add({ + // ctc::minus(ab,_w2,_w1), + // ctc::minus(at,t,w1), + // ctc::minus(ta,_w1,t), + // ctc::minus(tb,_w2,t), + // ctc::plus(mt,_m,t), + // ctc::minus(am,mt,w1), + // ctc::det(k1,ab,am), + // ctc::det(k2,ab,at), + // ctc::det(k3,_m,ta), + // ctc::det(k4,_m,tb), + // ctc::mul(z1,k1,k2), + // ctc::mul(z2,k3,k4), + // ctc::max(Interval(0,oo),z1,z2), + //}); +} + +void CtcNoCross::contract(IntervalVector& x) +{ + assert(x.size() == 2); + _ctc_cn.contract(x); +} \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcNoCross.h b/src/core/2/contractors/codac2_CtcNoCross.h new file mode 100644 index 000000000..622b568af --- /dev/null +++ b/src/core/2/contractors/codac2_CtcNoCross.h @@ -0,0 +1,45 @@ +/** + * \file + * + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_CTCNOCROSS__ +#define __CODAC2_CTCNOCROSS__ + +#include +#include +#include +#include +#include + +namespace codac2 +{ + /** + * \class CtcNoCross + */ + class CtcNoCross : public Ctc + { + public: + + CtcNoCross(const IntervalVector& w1, const IntervalVector& w2, const IntervalVector& m); + void contract(IntervalVector& x); + + make_available_to_cn() + + protected: + + const IntervalVector _w1, _w2, _m; + Var t, ab, mt, am, at, ta, tb; + Var z1, z2, k1, k2, k3, k4; + ContractorNetwork _cn; + CtcCN _ctc_cn; + }; +} + +#endif \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcPaver.h b/src/core/2/contractors/codac2_CtcPaver.h index 9d8318e8f..93a0b14f8 100644 --- a/src/core/2/contractors/codac2_CtcPaver.h +++ b/src/core/2/contractors/codac2_CtcPaver.h @@ -9,30 +9,72 @@ * the GNU Lesser General Public License (LGPL). */ -#ifndef __CODAC2_CTCONPAVER_H__ -#define __CODAC2_CTCONPAVER_H__ +#ifndef __CODAC2_CTCPAVER_H__ +#define __CODAC2_CTCPAVER_H__ -#include "codac2_Contractor.h" +#include "codac2_Ctc.h" +#include "codac2_Paving.h" namespace codac2 { - template - class CtcPaver : public Contractor + template + class CtcPaver : public Ctc { public: - static bool compare_paving(const std::weak_ptr>& first, const std::weak_ptr>& second) + //template + static bool compare_paving(const std::weak_ptr>& first, const std::weak_ptr>& second) { - return first.lock()->_x.volume() > second.lock()->_x.volume(); + return first.lock()->box().volume() > second.lock()->box().volume(); } - CtcPaver(ContractorOnBox& ctc, size_t max_leaves) + CtcPaver(C& ctc, size_t *max_leaves) : _ctc(ctc), _max_leaves(max_leaves) { } - void contract(Paving& x) + template + void contract(Paving_& x) + { + std::list>>& l_subpav = x.leaves(); + + auto it_leaves = l_subpav.begin(); + while(it_leaves != l_subpav.end()) + { + auto shared_leaf = it_leaves->lock(); + _ctc.contract(shared_leaf->box()); + + if(shared_leaf->box().is_empty()) + l_subpav.erase(it_leaves++); + + else + ++it_leaves; + } + + l_subpav.sort(compare_paving); + + while(l_subpav.size() < *_max_leaves) + { + std::shared_ptr> biggest_leaf = l_subpav.front().lock(); + l_subpav.pop_front(); + + if(!biggest_leaf->box().is_bisectable()) + l_subpav.push_back(biggest_leaf); + + else + { + biggest_leaf->bisect(); + _ctc.contract(biggest_leaf->left()->box()); + l_subpav.push_back(biggest_leaf->left()); + _ctc.contract(biggest_leaf->right()->box()); + l_subpav.push_back(biggest_leaf->right()); + } + } + } + + /*template + void contract(Paving_& x) { auto l_subpav = x.leaves(); size_t nb_leaves = l_subpav.size(); @@ -41,16 +83,16 @@ namespace codac2 { l_subpav.sort(compare_paving); - std::shared_ptr> q = l_subpav.front().lock(); + std::shared_ptr> q = l_subpav.front().lock(); l_subpav.pop_front(); assert(q.use_count() > 1); - _ctc.contract(q->_x); + _ctc.contract(q->box()); - if(q->_x.is_empty()) + if(q->box().is_empty()) nb_leaves--; - else if(nb_leaves < _max_leaves) + else if(nb_leaves < *_max_leaves && q->box().is_bisectable()) { q->bisect(); nb_leaves++; @@ -58,14 +100,34 @@ namespace codac2 l_subpav.push_back(q->right()); } } + }*/ + + template + std::list> get_default_spans(T&... x) + { + std::list> views; + (views.push_back(std::make_shared::type>>(&x)), ...); + for(auto& ctc : _ctc.get_default_spans(x...)) + views.push_back(ctc); + views.remove_if([](const std::shared_ptr& v) { return !v || v->cannot_propagate(); }); + return views; + } + + std::list> contract_and_propag(DomainNode&>& x) + { + contract(x.operator Paving&()); + std::list> output_views; + output_views.push_back(x.update_and_propag()); + /* keep this? */ output_views.remove_if([](const std::shared_ptr& v) { return !v || v->cannot_propagate(); }); + return output_views; } - make_available_in_cn__templated(CtcPaver) + make_available_to_cn___call_operator() protected: - ContractorOnBox& _ctc; - size_t _max_leaves; + C& _ctc; + size_t *_max_leaves; }; } diff --git a/src/core/2/contractors/codac2_CtcPolar.cpp b/src/core/2/contractors/codac2_CtcPolar.cpp new file mode 100644 index 000000000..c93192ef8 --- /dev/null +++ b/src/core/2/contractors/codac2_CtcPolar.cpp @@ -0,0 +1,35 @@ +/** + * CtcPolar class + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Benoît Desrochers + * \copyright Copyright 2021 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include +#include + +using namespace std; +using namespace codac2; + +CtcPolar::CtcPolar() +{ } + +void CtcPolar::contract(IntervalVector& x) +{ + assert(x.size() == 4); + contract(x[0], x[1], x[2], x[3]); +} + +void CtcPolar::contract(IntervalVector& xy, IntervalVector& rhotheta) +{ + assert(xy.size() == 2 && rhotheta.size() == 2); + contract(xy[0], xy[1], rhotheta[0], rhotheta[1]); +} + +void CtcPolar::contract(Interval& x, Interval& y, Interval& rho, Interval& theta) +{ + codac::ctc::polar.contract(x,y,rho,theta); +} \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcPolar.h b/src/core/2/contractors/codac2_CtcPolar.h new file mode 100644 index 000000000..22b543091 --- /dev/null +++ b/src/core/2/contractors/codac2_CtcPolar.h @@ -0,0 +1,37 @@ +/** + * \file + * + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Benoît Desrochers + * \copyright Copyright 2022 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_CTCPOLAR__ +#define __CODAC2_CTCPOLAR__ + +#include "codac2_Ctc.h" +#include "codac2_Interval.h" +#include "codac2_IntervalVector.h" + +namespace codac2 +{ + /** + * \class CtcPolar + */ + class CtcPolar : public Ctc + { + public: + + CtcPolar(); + void contract(IntervalVector& x); + void contract(IntervalVector& xy, IntervalVector& rhotheta); + void contract(Interval& x, Interval& y, Interval& rho, Interval& theta); + + make_available_to_cn() + }; +} + +#endif \ No newline at end of file diff --git a/src/core/2/contractors/codac2_CtcUnion.h b/src/core/2/contractors/codac2_CtcUnion.h new file mode 100644 index 000000000..d2ada6706 --- /dev/null +++ b/src/core/2/contractors/codac2_CtcUnion.h @@ -0,0 +1,84 @@ +/** + * \file + * CtcUnion class + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_CTCUNION_H__ +#define __CODAC2_CTCUNION_H__ + +#include +//#include "ibex_CtcUnion.h" +#include "codac2_Ctc.h" + +namespace codac2 +{ + class CollectionCtc + { + public: + + CollectionCtc() + { } + + template + CollectionCtc(const C&... c) + { + (add_shared_ptr(std::make_shared(c)), ...); + } + + template + void add_shared_ptr(std::shared_ptr shrd_ptr) + { + _v_ctc.push_back(shrd_ptr); + _v_ctc_ptrs.push_back(shrd_ptr.get()); + } + + void add_raw_ptr(BoxCtc *c) + { + _v_ctc_ptrs.push_back(c); + } + + protected: + + std::vector> _v_ctc; + std::vector _v_ctc_ptrs; + }; + + class CtcUnion : public CollectionCtc, public BoxCtc + { + public: + + template + CtcUnion(const C&... c) : CollectionCtc(c...) + { } + + void contract(IntervalVector& x) + { + auto result = x; + result.set_empty(); + + for(auto& ci : _v_ctc_ptrs) + { + auto saved_x = x; + ci->contract(saved_x); + result |= saved_x; + } + + x = result; + } + + template + CtcUnion& operator|=(const C& c) + { + add_shared_ptr(std::make_shared(c)); + return *this; + } + }; +} + +#endif \ No newline at end of file diff --git a/src/core/2/contractors/codac2_arithmetic_ctc.cpp b/src/core/2/contractors/codac2_arithmetic_ctc.cpp new file mode 100644 index 000000000..d616f5cd1 --- /dev/null +++ b/src/core/2/contractors/codac2_arithmetic_ctc.cpp @@ -0,0 +1,23 @@ +/** + * + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_arithmetic_ctc.h" + +namespace codac2 +{ + //namespace ctc + //{ + // CtcPlus plus; + // CtcMinus minus; + // CtcMul mul; + // CtcDet det; + // CtcMax max; + //} +} \ No newline at end of file diff --git a/src/core/2/contractors/codac2_arithmetic_ctc.h b/src/core/2/contractors/codac2_arithmetic_ctc.h new file mode 100644 index 000000000..13ab0793b --- /dev/null +++ b/src/core/2/contractors/codac2_arithmetic_ctc.h @@ -0,0 +1,142 @@ +/** + * \file + * + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou + * \copyright Copyright 2022 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_CTCMINUS__ +#define __CODAC2_CTCMINUS__ + +#include "codac2_Ctc.h" +#include "codac2_Interval.h" +#include "codac2_IntervalVector.h" + +namespace codac2 +{ +// /** +// * \class CtcMinus +// */ +// class CtcMinus : public Ctc +// { +// public: +// +// CtcMinus() +// { } +// +// void contract(Interval& a, Interval& b, Interval& c) +// { +// a &= b-c; b &= a+c; c &= b-a; +// } +// +// void contract(IntervalVector& a, IntervalVector& b, IntervalVector& c) +// { +// a &= b-c; b &= a+c; c &= b-a; +// } +// +// make_available_to_cn() +// }; +// +// /** +// * \class CtcPlus +// */ +// class CtcPlus : public Ctc +// { +// public: +// +// CtcPlus() +// { } +// +// void contract(Interval& a, Interval& b, Interval& c) +// { +// a &= b+c; b &= a-c; c &= a-b; +// } +// +// void contract(IntervalVector& a, IntervalVector& b, IntervalVector& c) +// { +// a &= b+c; b &= a-c; c &= a-b; +// } +// +// make_available_to_cn() +// }; +// +// /** +// * \class CtcMul +// */ +// class CtcMul : public Ctc +// { +// public: +// +// CtcMul() +// { } +// +// void contract(Interval& z, Interval& x, Interval& y) +// { +// z &= x*y; x &= z/y; y &= z/x; +// bwd_mul(z,x,y); +// } +// +// make_available_to_cn() +// }; +// +// /** +// * \class CtcDet +// */ +// class CtcDet : public Ctc +// { +// public: +// +// CtcDet() +// { } +// +// void contract(Interval& det, IntervalVector& u, IntervalVector& v) +// { +// assert(u.size() == v.size()); +// +// CtcMinus ctc_minus; +// CtcMul ctc_mul; +// +// Interval z1 = u[0]*v[1]; +// Interval z2 = v[0]*u[1]; +// ctc_minus.contract(det,z1,z2); +// ctc_mul.contract(z2,v[0],u[1]); +// ctc_mul.contract(z1,u[0],v[1]); +// } +// +// make_available_to_cn() +// }; +// +// /** +// * \class CtcMax +// */ +// class CtcMax : public Ctc +// { +// public: +// +// CtcMax() +// { } +// +// void contract(Interval& m, Interval& z1, Interval& z2) +// { +// m &= max(z1,z2); +// bwd_max(m,z1,z2); +// } +// +// make_available_to_cn(); +// }; +// +// namespace ctc +// { +// extern CtcPlus plus; +// extern CtcMinus minus; +// extern CtcMul mul; +// extern CtcDet det; +// extern CtcMax max; +// } +} + +#endif \ No newline at end of file diff --git a/src/core/2/contractors/codac2_linear_ctc.cpp b/src/core/2/contractors/codac2_linear_ctc.cpp new file mode 100644 index 000000000..71b5c4e0d --- /dev/null +++ b/src/core/2/contractors/codac2_linear_ctc.cpp @@ -0,0 +1,54 @@ +/** + * Contractors for linear systems of equations + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include "codac2_linear_ctc.h" + +using namespace std; +using namespace codac2; + +void CtcGaussElim::contract(IntervalMatrix& A, IntervalVector& x, IntervalVector& b) +{ + assert(A.rows() == A.cols() && A.rows() == x.size() && A.rows() == b.size()); + + IntervalMatrix A_ = A; + IntervalVector b_ = b; + + size_t n = A_.rows(); + for(size_t i = 0 ; i < n ; i++) + if(A_(i,i).contains(0.)) + return; + + for(size_t i = 0 ; i < n-1 ; i++) + for(size_t j = i+1 ; j < n ; j++) + { + Interval aj = A_(j,i)/A_(i,i); + b_[j] -= aj*b_[i]; + for(size_t k = i+1 ; k < n ; k++) + A_(j,k) -= aj*A_(i,k); + } + + for(int i = n-1 ; i >= 0 ; i--) + { + Interval sum = 0.; + for(size_t j = i+1 ; j < n ; j++) + sum += A_(i,j)*x[j]; + x[i] &= (b_[i]-sum)/A_(i,i); + } +} + +void CtcGaussSeidel::contract(IntervalMatrix& A, IntervalVector& x, IntervalVector& b) +{ + assert(A.rows() == A.cols() && A.rows() == x.size() && A.rows() == b.size()); + + auto ext_diag = A; + for(size_t i = 0 ; i < A.rows() ; i++) + ext_diag(i,i) = 0.; + x &= A.diagonal_matrix().inverse().toDenseMatrix()*(b-ext_diag*x); +} \ No newline at end of file diff --git a/src/core/2/contractors/codac2_linear_ctc.h b/src/core/2/contractors/codac2_linear_ctc.h new file mode 100644 index 000000000..f71de072b --- /dev/null +++ b/src/core/2/contractors/codac2_linear_ctc.h @@ -0,0 +1,179 @@ +/** + * \file + * Contractors for linear systems of equations + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Luc Jaulin + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_LINEARCTC__ +#define __CODAC2_LINEARCTC__ + +#include +#include +#include + +namespace codac2 +{ + /** + * \brief Contractor for a linear system of interval equations, + * based on the classical Gauss elimination procedure. + * + * No preconditioning is done (see `CtcLinearPrecond` for preconditioning). + * + * The associated constraint is under the form \f$\mathbf{A}\cdot\mathbf{x}=\mathbf{b}\f$, + * where \f$\mathbf{A}\f$ is a squared matrix in \f$\mathbb{R}^{n\times n}\f$ and + * \f$\mathbf{c}\f$, \f$\mathbf{b}\f$ vectors in \f$\mathbb{R}^{n}\f$. + * + * Note that because the condition \f$0\in[a_{ii}]\f$ is frequently satisfied for + * some \f$i\f$, this contractor often fails to contract. It is however efficient, + * for instance, when the interval matrix \f$[\mathbf{A}]\f$ is close to the identity matrix. + * See the `CtcLinearPrecond` for this purpose. + * + * Note also that this contractor is idempotent: if it is run again, + * \f$[\mathbf{x}]\f$ is not contracted any more. + * + * Reference: + * Applied Interval Analysis + * Luc Jaulin, Michel Kieffer, Olivier Didrit, Éric Walter + * 2001, Springer London + * doi: https://doi.org/10.1007/978-1-4471-0249-6 + * Sec 4.2.2, Page 70 + */ + class CtcGaussElim : public Ctc + { + public: + + /** + * \brief Creates a contractor based on the Gauss elimination. + */ + CtcGaussElim() + { } + + /** + * \brief Creates the domains according to the linear system: + * \f$\mathbf{A}\cdot\mathbf{x}=\mathbf{b}\f$ + * + * \param A the domain \f$[\mathbf{A}]\f$ + * \param x the domain \f$[\mathbf{x}]\f$ + * \param b the domain \f$[\mathbf{b}]\f$ + */ + void contract(IntervalMatrix& A, IntervalVector& x, IntervalVector& b); + }; + + /** + * \brief Contractor for a linear system of interval equations, + * using a fixed-point approach based on the Gauss Seidel method. + * + * No preconditioning is done (see `CtcLinearPrecond` for preconditioning). + * + * The associated constraint is under the form \f$\mathbf{A}\cdot\mathbf{x}=\mathbf{b}\f$, + * where \f$\mathbf{A}\f$ is a squared matrix in \f$\mathbb{R}^{n\times n}\f$ and + * \f$\mathbf{c}\f$, \f$\mathbf{b}\f$ vectors in \f$\mathbb{R}^{n}\f$, provided that + * \f$\textrm{diag}(\mathbf{A})\f$ is invertible (i.e., \f$\mathbf{A}\f$ has no zero entry + * on its diagonal), + * + * Note that it is efficient when the interval matrix \f$[\mathbf{A}]\f$ is close + * to the identity matrix. See the `CtcLinearPrecond` for this purpose. + * + * Note also that this contractor is not idempotent, better improvements can be obtained + * with successive calls. + * + * Reference: + * Applied Interval Analysis + * Luc Jaulin, Michel Kieffer, Olivier Didrit, Éric Walter + * 2001, Springer London + * doi: https://doi.org/10.1007/978-1-4471-0249-6 + * Sec 4.2.3, Page 73 + */ + class CtcGaussSeidel : public Ctc + { + public: + + /** + * \brief Creates a contractor based on the Gauss Seidel method. + */ + CtcGaussSeidel() + { } + + /** + * \brief Creates the domains according to the linear system: + * \f$\mathbf{A}\cdot\mathbf{x}=\mathbf{b}\f$ + * + * \param A the domain \f$[\mathbf{A}]\f$ + * \param x the domain \f$[\mathbf{x}]\f$ + * \param b the domain \f$[\mathbf{b}]\f$ + */ + void contract(IntervalMatrix& A, IntervalVector& x, IntervalVector& b); + }; + + /** + * \brief Contractor for a linear system of interval equations, + * using a preconditioning method before calling some provided contractor. + * + * The associated constraint is under the form \f$\mathbf{A}\cdot\mathbf{x}=\mathbf{b}\f$, + * where \f$\mathbf{A}\f$ is a squared matrix in \f$\mathbb{R}^{n\times n}\f$ and + * \f$\mathbf{c}\f$, \f$\mathbf{b}\f$ vectors in \f$\mathbb{R}^{n}\f$. + * + * Contractors such as `CtcGaussElim` or `CtcGaussSeidel` are then likely to be efficient + * if they act on \f$\mathbf{A}\f$ matrices close to the identity. + * This can be achieved provided that \f$w([\mathbf{A}])\f$ is small enough and that some + * selected \f$\mathbf{A0}\f$ in \f$[\mathbf{A}]\f$ is well conditioned. + * + * Reference: + * Applied Interval Analysis + * Luc Jaulin, Michel Kieffer, Olivier Didrit, Éric Walter + * 2001, Springer London + * doi: https://doi.org/10.1007/978-1-4471-0249-6 + * Sec 4.3.2, Page 84 + */ + template + class CtcLinearPrecond : public Ctc + { + public: + + /** + * \brief Creates a contractor performing preconditioning before calling + * some provided linear contractor. + * + * \param ctc_no_precond contractor object performing the contraction of a linear + * system of equations, in the case of well-conditioned systems (when the interval + * matrix \f$[\mathbf{A}]\f$ is close to the identity matrix). + */ + CtcLinearPrecond(C& ctc_no_precond) : _ctc_no_precond(ctc_no_precond) + { } + + /** + * \brief Creates the domains according to the linear system: + * \f$\mathbf{A}\cdot\mathbf{x}=\mathbf{b}\f$ + * + * \param A the domain \f$[\mathbf{A}]\f$ + * \param x the domain \f$[\mathbf{x}]\f$ + * \param b the domain \f$[\mathbf{b}]\f$ + */ + void contract(IntervalMatrix& A, IntervalVector& x, IntervalVector& b) + { + assert(A.rows() == A.cols() && A.rows() == x.size() && A.rows() == b.size()); + + auto A0 = A.mid(); + Matrix A0_inv = A0.inverse(); + IntervalMatrix Ap = IntervalMatrix(A0_inv)*A; + IntervalVector bp = IntervalMatrix(A0_inv)*b; + + _ctc_no_precond.contract(Ap,x,bp); + + b &= IntervalMatrix(A0)*bp; + A &= IntervalMatrix(A0)*Ap; + } + + + protected: + + C& _ctc_no_precond; + }; +} + +#endif \ No newline at end of file diff --git a/src/core/2/domains/interval/codac2_Interval.h b/src/core/2/domains/interval/codac2_Interval.h index 1e9c29bd0..1332eab7d 100644 --- a/src/core/2/domains/interval/codac2_Interval.h +++ b/src/core/2/domains/interval/codac2_Interval.h @@ -29,6 +29,8 @@ namespace codac2 { public: + using DegeneratedType = double; + Interval(); Interval(double a); Interval(double a, double b); diff --git a/src/core/2/domains/interval/codac2_IntervalMatrix.h b/src/core/2/domains/interval/codac2_IntervalMatrix.h index 63b0f2a60..037adb578 100644 --- a/src/core/2/domains/interval/codac2_IntervalMatrix.h +++ b/src/core/2/domains/interval/codac2_IntervalMatrix.h @@ -175,6 +175,14 @@ namespace codac2 return false; } + bool is_degenerated() const + { + for(size_t i = 0 ; i < size() ; i++) + if(!(this->data()+i)->is_degenerated()) + return false; + return true; + } + bool is_unbounded() const { if(is_empty()) return false; @@ -595,8 +603,6 @@ namespace codac2 return Interval(a)*x; } - using IntervalMatrix = IntervalMatrix_<>; - /*class IntervalMatrix : public IntervalMatrix_<> { public: @@ -633,6 +639,8 @@ namespace codac2 } };*/ + using IntervalMatrix = IntervalMatrix_<>; + } // namespace codac #endif \ No newline at end of file diff --git a/src/core/2/domains/interval/codac2_IntervalVector.cpp b/src/core/2/domains/interval/codac2_IntervalVector.cpp new file mode 100644 index 000000000..96795e140 --- /dev/null +++ b/src/core/2/domains/interval/codac2_IntervalVector.cpp @@ -0,0 +1,270 @@ +/** + * \file + * + * ---------------------------------------------------------------------------- + * \date 2022 + * \author Simon Rohou + * \copyright Copyright 2022 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include +#include "codac2_IntervalVector.h" + +using namespace std; + +namespace codac2 +{ + // Class IntervalVector + + /*IntervalVector::IntervalVector(size_t n) + : IntervalVector_<>(n) + { } + + IntervalVector::IntervalVector(size_t n, const Interval& x) + : IntervalVector_<>(n, x) + { } + + //IntervalVector::IntervalVector(const Interval& x) + // : IntervalVector_<>({x}) + //{ } + + IntervalVector::IntervalVector(const IntervalVector& x) + : IntervalVector_<>(x) + { } + + IntervalVector::IntervalVector(size_t n, const double bounds[][2]) + : IntervalVector_<>(n, bounds) + { } + + IntervalVector::IntervalVector(std::initializer_list l) + : IntervalVector_<>(l) + { + assert(l.size() > 0); + } + + IntervalVectorComponent IntervalVector::operator[](size_t i) + { + return IntervalVectorComponent(*this, i); + } + + IntervalVectorSubvector IntervalVector::operator[](std::array i) + { + return IntervalVectorSubvector(*this, i); + } + + IntervalVectorConstComponent IntervalVector::operator[](size_t i) const + { + return IntervalVectorConstComponent(*this, i); + } + + IntervalVectorConstSubvector IntervalVector::operator[](std::array i) const + { + return IntervalVectorConstSubvector(*this, i); + } + + void IntervalVector::resize(size_t n) + { + this->IntervalVector_<>::resize(n); + } + + IntervalVector IntervalVector::empty_set(size_t n) + { + return IntervalMatrix_<>::empty_set(n,1); + }*/ + + // Class IntervalVectorComponent +#if 0 + IntervalVectorComponent::IntervalVectorComponent(IntervalVector& x, size_t i) + : /*Interval(x.i(i)),*/ _x(x), _i(i) + { + //#ifndef NDEBUG + set_name(x.name() + "[" + std::to_string(i) + "]"); + //#endif + } + + IntervalVectorComponent& IntervalVectorComponent::operator=(const IntervalVectorComponent& xi) + { + _x.i(_i) = xi; + return *this; + } + + IntervalVectorComponent& IntervalVectorComponent::operator=(const Interval& xi) + { + _x.i(_i) = xi; + return *this; + } + + IntervalVectorComponent& IntervalVectorComponent::operator&=(const Interval& xi) + { + _x.i(_i) &= xi; + return *this; + } + + IntervalVectorComponent& IntervalVectorComponent::operator|=(const Interval& xi) + { + _x.i(_i) |= xi; + return *this; + } + + IntervalVectorComponent& IntervalVectorComponent::operator+=(const Interval& xi) + { + _x.i(_i) += xi; + return *this; + } + + IntervalVectorComponent& IntervalVectorComponent::operator-=(const Interval& xi) + { + _x.i(_i) -= xi; + return *this; + } + + IntervalVectorComponent& IntervalVectorComponent::operator*=(const Interval& xi) + { + _x.i(_i) *= xi; + return *this; + } + + IntervalVectorComponent& IntervalVectorComponent::operator/=(const Interval& xi) + { + _x.i(_i) /= xi; + return *this; + } + + Interval& IntervalVectorComponent::operator()() + { + return _x.i(_i); + } + + const Interval& IntervalVectorComponent::operator()() const + { + return _x.i(_i); + } + + IntervalVectorComponent::operator Interval&() + { + return _x.i(_i); + } + + IntervalVectorComponent::operator const Interval&() const + { + return _x.i(_i); + } + + IntervalVectorComponent& IntervalVectorComponent::inflate(double r) + { + _x.i(_i).inflate(r); + return *this; + } + + std::ostream& operator<<(std::ostream& os, const IntervalVectorComponent& p) + { + os << p.operator const Interval&(); + return os; + } + + // Class IntervalVectorConstComponent + + IntervalVectorConstComponent::IntervalVectorConstComponent(const IntervalVector& x, size_t i) + : Interval(x.i(i)), _x(x), _i(i) + { + + } + + const Interval& IntervalVectorConstComponent::operator()() const + { + return _x.i(_i); + } + + // Class IntervalVectorSubvector + + IntervalVectorSubvector::IntervalVectorSubvector(IntervalVector& x, const std::array& i) + : IntervalVector(x.subvector(i[0],i[1])), _x(x), _i(i) + { + + } + + IntervalVectorSubvector& IntervalVectorSubvector::operator=(const IntervalVectorSubvector& xi) + { + assert(_i[1]-_i[0] == xi._i[1]-xi._i[0]); + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) = xi[j-_i[0]]; + return *this; + } + + const IntervalVectorSubvector& IntervalVectorSubvector::operator=(const IntervalVectorSubvector& xi) const + { + assert(_i[1]-_i[0] == xi._i[1]-xi._i[0]); + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) = xi[j-_i[0]]; + return *this; + } + + IntervalVectorSubvector& IntervalVectorSubvector::operator=(const IntervalVector& xi) + { + assert(_i[1]-_i[0]+1 == xi.size()); + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) = xi[j-_i[0]]; + return *this; + } + + const IntervalVectorSubvector& IntervalVectorSubvector::operator=(const IntervalVector& xi) const + { + assert(_i[1]-_i[0]+1 == xi.size()); + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) = xi[j-_i[0]]; + return *this; + } + + IntervalVectorSubvector& IntervalVectorSubvector::operator&=(const IntervalVector& xi) + { + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) &= xi[j-_i[0]]; + return *this; + } + + IntervalVectorSubvector& IntervalVectorSubvector::operator|=(const IntervalVector& xi) + { + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) |= xi[j-_i[0]]; + return *this; + } + + IntervalVectorSubvector& IntervalVectorSubvector::operator+=(const IntervalVector& xi) + { + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) += xi[j-_i[0]]; + return *this; + } + + IntervalVectorSubvector& IntervalVectorSubvector::operator-=(const IntervalVector& xi) + { + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) -= xi[j-_i[0]]; + return *this; + } + + IntervalVectorSubvector& IntervalVectorSubvector::operator*=(const IntervalVector& xi) + { + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) *= xi[j-_i[0]]; + return *this; + } + + IntervalVectorSubvector& IntervalVectorSubvector::operator/=(const IntervalVector& xi) + { + for(size_t j = _i[0] ; j <= _i[1] ; j++) + _x.i(j) /= xi[j-_i[0]]; + return *this; + } + + // Class IntervalVectorConstSubvector + + IntervalVectorConstSubvector::IntervalVectorConstSubvector(const IntervalVector& x, const std::array& i) + : IntervalVector(x.subvector(i[0],i[1])), _x(x), _i(i) + { + + } +#endif +} // namespace codac \ No newline at end of file diff --git a/src/core/2/domains/interval/codac2_IntervalVector.h b/src/core/2/domains/interval/codac2_IntervalVector.h index 1b4d9df33..79fdaa5b4 100644 --- a/src/core/2/domains/interval/codac2_IntervalVector.h +++ b/src/core/2/domains/interval/codac2_IntervalVector.h @@ -295,8 +295,6 @@ namespace codac2 return x_; } - using IntervalVector = IntervalVector_<>; - /*class IntervalVector : public IntervalVector_<> { @@ -506,6 +504,8 @@ namespace codac2 // const std::array _i; // }; + using IntervalVector = IntervalVector_<>; + } // namespace codac #endif \ No newline at end of file diff --git a/src/core/2/domains/interval/codac2_IntervalVectorComponent.h b/src/core/2/domains/interval/codac2_IntervalVectorComponent.h new file mode 100644 index 000000000..f3ca8d73e --- /dev/null +++ b/src/core/2/domains/interval/codac2_IntervalVectorComponent.h @@ -0,0 +1,193 @@ +/** + * \file + * + * This class reuses many of the functions developed for ibex::IntervalVector. + * The original IBEX code is revised in modern C++ and adapted to the template + * structure proposed in Codac, based on the Eigen library. + * See ibex::IntervalVector (IBEX lib, author: G. Chabert) + * + * ---------------------------------------------------------------------------- + * \date 2023 + * \author Simon Rohou + * \copyright Copyright 2023 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#ifndef __CODAC2_INTERVALVECTORCOMPONENT_H__ +#define __CODAC2_INTERVALVECTORCOMPONENT_H__ + +#include + +namespace codac2 +{ + template + class IntervalVector_; + + template + class IntervalVectorComponent_ : public Interval + { + public: + + IntervalVectorComponent_(IntervalVector_& x, size_t i) + : _x(x), _i(i), Interval(_x.i(_i)) + { + set_name(x.name() + "[" + std::to_string(i) + "]"); + } + + IntervalVectorComponent_& operator=(const IntervalVectorComponent_& xi) + { + _x.i(_i) = xi; + return *this; + } + + IntervalVectorComponent_& operator=(const Interval& xi) + { + _x.i(_i) = xi; + return *this; + } + + bool operator==(const IntervalVectorComponent_& xi) + { + return &_x == &xi._x && &_i == &xi._i; + } + + bool operator!=(const IntervalVectorComponent_& xi) + { + return &_x != &xi._x || &_i != &xi._i; + } + + IntervalVectorComponent_& operator&=(const Interval& xi) + { + _x.i(_i) &= xi; + return *this; + } + + IntervalVectorComponent_& operator|=(const Interval& xi) + { + _x.i(_i) |= xi; + return *this; + } + + IntervalVectorComponent_& operator+=(const Interval& xi) + { + _x.i(_i) += xi; + return *this; + } + + IntervalVectorComponent_& operator-=(const Interval& xi) + { + _x.i(_i) -= xi; + return *this; + } + + IntervalVectorComponent_& operator*=(const Interval& xi) + { + _x.i(_i) *= xi; + return *this; + } + + IntervalVectorComponent_& operator/=(const Interval& xi) + { + _x.i(_i) /= xi; + return *this; + } + + /*template + Interval operator+(const T& x) const + { + return operator const Interval&() + x; + } + + template + Interval operator-(const T& x) const + { + return operator const Interval&() - x; + }*/ + + Interval& operator()() + { + return _x.i(_i); + } + + /*const Interval& operator()() const + { + return _x.i(_i); + }*/ + + /*operator Interval() + { + return _x.i(_i); + }*/ + + /*operator Interval&() + { + return _x.i(_i); + }*/ + + /*operator const Interval&() const + { + return _x.i(_i); + }*/ + + IntervalVectorComponent_& inflate(double r) + { + _x.i(_i).inflate(r); + return *this; + } + + double volume() const + { + return _x.i(_i).diam(); + } + + friend std::ostream& operator<<(std::ostream& os, const IntervalVectorComponent_& p) + { + os << p.operator const Interval&(); + return os; + } + + //protected: + + IntervalVector_& _x; + const size_t _i; + }; + + using IntervalVectorComponent = IntervalVectorComponent_<>; + + + template + class IntervalVectorConstComponent_ : public Interval + { + public: + + IntervalVectorConstComponent_(const IntervalVector_& x, size_t i) + : Interval(x.i(i)), _x(x), _i(i) + { + set_name(x.name() + "[" + std::to_string(i) + "]"); + } + + IntervalVectorConstComponent_& operator=(const IntervalVectorConstComponent_& xi) = delete; + IntervalVectorConstComponent_& operator=(const Interval& xi) = delete; + + bool operator==(const IntervalVectorConstComponent_& xi) + { + return &_x == &xi._x && &_i == &xi._i; + } + + bool operator!=(const IntervalVectorConstComponent_& xi) + { + return &_x != &xi._x || &_i != &xi._i; + } + + //protected: + + const IntervalVector_& _x; + const size_t _i; + }; + + using IntervalVectorConstComponent = IntervalVectorConstComponent_<>; + +} // namespace codac + +#endif \ No newline at end of file diff --git a/src/core/2/domains/interval/codac2_cart_prod.h b/src/core/2/domains/interval/codac2_cart_prod.h index f9a939b6d..876c1777b 100644 --- a/src/core/2/domains/interval/codac2_cart_prod.h +++ b/src/core/2/domains/interval/codac2_cart_prod.h @@ -62,7 +62,7 @@ namespace codac2 template IntervalVector cart_prod(const T1& x1, const T2& x2, const Args&... xi) // recursive variadic function { - IntervalVector x_ = cart_prod_dyn(IntervalVector(x1), IntervalVector(x2)); + IntervalVector x_ = cart_prod_dyn(x1, x2); if constexpr(sizeof...(xi) > 0) return cart_prod(x_, xi...); else diff --git a/src/core/2/domains/paving/codac2_Paving.cpp b/src/core/2/domains/paving/codac2_Paving.cpp new file mode 100644 index 000000000..389df66a5 --- /dev/null +++ b/src/core/2/domains/paving/codac2_Paving.cpp @@ -0,0 +1,20 @@ +/** + * \file + * + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou + * \copyright Copyright 2024 Codac Team + * \license This program is distributed under the terms of + * the GNU Lesser General Public License (LGPL). + */ + +#include +#include "codac2_Paving.h" + +using namespace std; + +namespace codac2 +{ + +} // namespace codac \ No newline at end of file diff --git a/src/core/2/domains/paving/codac2_Paving.h b/src/core/2/domains/paving/codac2_Paving.h index e1445fa97..afe80bb74 100644 --- a/src/core/2/domains/paving/codac2_Paving.h +++ b/src/core/2/domains/paving/codac2_Paving.h @@ -21,31 +21,36 @@ namespace codac2 { - template - class Paving; + template + class Paving_; template - class PavingNode : public std::enable_shared_from_this> + class PavingNode_ : public std::enable_shared_from_this> { public: - explicit PavingNode(Paving& paving, const IntervalVector_& x) + explicit PavingNode_(Paving_& paving, const IntervalVector_& x) : _paving(paving), _x(x) { } - virtual ~PavingNode() = default; + virtual ~PavingNode_() = default; const IntervalVector_& box() const { return _x; } - std::shared_ptr> left() + IntervalVector_& box() + { + return _x; + } + + std::shared_ptr> left() { return _left; } - std::shared_ptr> right() + std::shared_ptr> right() { return _right; } @@ -71,11 +76,11 @@ namespace codac2 assert(_x.is_bisectable()); auto p = _x.bisect(ratio); - _left = std::make_shared>(_paving, p.first); - _right = std::make_shared>(_paving, p.second); + _left = std::make_shared>(_paving, p.first); + _right = std::make_shared>(_paving, p.second); auto wp = this->weak_from_this(); - _paving._leaves.remove_if([wp](std::weak_ptr> p) + _paving._leaves.remove_if([wp](std::weak_ptr> p) { auto swp = wp.lock(), sp = p.lock(); if(swp && sp) return swp == sp; @@ -89,53 +94,88 @@ namespace codac2 protected: template - friend class Paving; + friend class Paving_; - void recurse__boxes_list(std::list>>& l, const IntervalVector_& intersect = IntervalVector_()) const + void recurse__boxes_list(std::list>>& l, const IntervalVector_& intersect) const { - if(is_leaf() && !_x.is_empty() && _x.intersects(intersect)) + if(is_leaf() && !_x.is_empty()/* && _x.intersects(intersect)*/) // todo l.push_back(std::cref(_x)); else { - if(_left) _left->recurse__boxes_list(l); - if(_right) _right->recurse__boxes_list(l); + if(_left) _left->recurse__boxes_list(l, intersect); + if(_right) _right->recurse__boxes_list(l, intersect); } } - public: // todo + void recurse__contract(IntervalVector_& x) + { + if(is_leaf()) + x &= _x; + + else if(!x.intersects(_x)) + x.set_empty(); + + else + { + IntervalVector_& x_left(x), x_right(x); + if(_left) _left->recurse__contract(x_left); + if(_right) _right->recurse__contract(x_right); + x = x_left | x_right; + } + } + + protected: + Paving_& _paving; IntervalVector_ _x; - //std::weak_ptr> _parent = nullptr; - std::shared_ptr> _left = nullptr, _right = nullptr; - Paving& _paving; + //std::weak_ptr> _parent = nullptr; + std::shared_ptr> _left = nullptr, _right = nullptr; }; - template - class Paving : public Domain + template + class Paving_ : public Domain { public: - explicit Paving(size_t n) - : Paving(IntervalVector_(n)) - { } + explicit Paving_(size_t n = N) + : Paving_(IntervalVector_(n)) + { + assert(n > 0); + } - explicit Paving(const IntervalVector_& x) - : _tree(std::make_shared>(*this, IntervalVector_(x))) + explicit Paving_(const IntervalVector_& x) + : _tree(std::make_shared>(*this, x)) { _leaves.push_back(_tree->weak_from_this()); } - Paving(const Paving&) = delete; - Paving& operator=(const Paving&) = delete; + Paving_(const Paving_& x) + : _leaves(x._leaves), _tree(x._tree) + { + + } + + Paving_& operator=(const Paving_& x) + { + _leaves = x._leaves; + _tree = x._tree; + return *this; + } + + size_t size() const + { + return _tree->_x.size(); + } size_t nb_leaves() const { + update_leaves(); return _leaves.size(); } IntervalVector_ hull_box() const { - IntervalVector_ hull = IntervalVector_::empty_set(); + IntervalVector_ hull = IntervalVector_::empty_set(size()); for(const auto& l : _leaves) hull |= l.lock()->box(); return hull; @@ -156,39 +196,51 @@ namespace codac2 vol += l.lock()->box().volume(); return vol; } - - DomainVolume dom_volume() const + + void update_leaves() const { - DomainVolume vol; - for(const auto& l : _leaves) - vol.push_back(l.lock()->box().volume()); - return vol; + _leaves.remove_if([](std::weak_ptr> p) + { + auto sp = p.lock(); + return sp->box().is_empty(); + }); } - std::list>>& leaves() + std::list>>& leaves() { + update_leaves(); return _leaves; } - std::list>> boxes_list(const IntervalVector_& intersect = IntervalVector_()) const + std::list>> boxes_list() const + { + return boxes_list(IntervalVector_(size())); + } + + std::list>> boxes_list(const IntervalVector_& intersect) const { std::list>> l; _tree->recurse__boxes_list(l, intersect); return l; } + void contract(IntervalVector_& x) + { + _tree->recurse__contract(x); + } + template - friend class PavingNode; + friend class PavingNode_; template - friend std::ostream& operator<<(std::ostream& os, const Paving& p); + friend std::ostream& operator<<(std::ostream& os, const Paving_& p); public: // todo - using leaves_container = std::list>>; - leaves_container _leaves; - std::shared_ptr> _tree; // must be a shared_ptr to allow enable_shared_from_this + using leaves_container = std::list>>; + mutable leaves_container _leaves; + std::shared_ptr> _tree; // must be a shared_ptr to allow enable_shared_from_this public: @@ -209,14 +261,15 @@ namespace codac2 auto end() const { return const_iterator(_leaves.cend()); } }; - template - inline std::ostream& operator<<(std::ostream& os, const Paving& p) + template + inline std::ostream& operator<<(std::ostream& os, const Paving_& p) { size_t n = p.nb_leaves(); - os << "Paving (" << n << " box" << (n > 1 ? "es)" : ")") << std::flush; + os << "Paving (" << n << " box" << (n > 1 ? "es" : "") << ", hull=" << p.hull_box() << ")" << std::flush; return os; } + using Paving = Paving_<>; } // namespace codac diff --git a/src/core/2/domains/tube/codac2_TDomain.cpp b/src/core/2/domains/tube/codac2_TDomain.cpp index 48ec3ac7f..23c975ec1 100644 --- a/src/core/2/domains/tube/codac2_TDomain.cpp +++ b/src/core/2/domains/tube/codac2_TDomain.cpp @@ -197,7 +197,7 @@ namespace codac2 assert(dt >= 0.); assert(!t0_tf.is_degenerated()); for(double t = t0_tf.lb() ; t < t0_tf.ub()+dt ; t=t+dt) - sample(min(t0_tf.ub(),t), with_gates); + sample(std::min(t0_tf.ub(),t), with_gates); } const list& TDomain::tslices() const diff --git a/src/core/2/domains/tube/codac2_TDomain.h b/src/core/2/domains/tube/codac2_TDomain.h index dde1191b2..0279adb73 100644 --- a/src/core/2/domains/tube/codac2_TDomain.h +++ b/src/core/2/domains/tube/codac2_TDomain.h @@ -18,7 +18,6 @@ #include #include "codac2_Interval.h" -#include "codac_predef_values.h" namespace codac2 { diff --git a/src/core/2/domains/tube/codac2_Tube.h b/src/core/2/domains/tube/codac2_Tube.h index 9cbb12d10..6c687a8d7 100644 --- a/src/core/2/domains/tube/codac2_Tube.h +++ b/src/core/2/domains/tube/codac2_Tube.h @@ -19,6 +19,7 @@ #include "codac2_IntervalVector.h" #include "codac2_AbstractSlicedTube.h" #include "codac2_AbstractConstTube.h" +#include "codac2_TubeEvaluation.h" #include "codac2_TDomain.h" #include "codac_ConvexPolygon.h" #include @@ -30,15 +31,15 @@ namespace codac2 template class Slice; - template - class TubeEvaluation; + //template + //class TubeEvaluation; template class ConstTubeEvaluation; template class TubeComponent; template - class Tube : public AbstractSlicedTube, public AbstractConstTube> + class Tube : public AbstractSlicedTube, public AbstractConstTube>, public Domain { public: @@ -60,7 +61,7 @@ namespace codac2 s.set(f.eval(s.t0_tf())); else - s.set(f.eval_vector(s.t0_tf())); + s.set(to_codac2(f.eval_vector(s.t0_tf()))); if(s.is_empty()) std::cout << "IS EMPTY: " << s << std::endl; @@ -361,6 +362,12 @@ namespace codac2 return true; } + bool operator!=(const Tube& x) const + { + return !operator==(x); + // todo: implement faster operator + } + Tube operator&=(const Tube& x) { assert(TDomain::are_same(tdomain(), x.tdomain())); diff --git a/src/core/2/domains/tube/codac2_TubeEvaluation.h b/src/core/2/domains/tube/codac2_TubeEvaluation.h index eb3d78ef2..ba8b6e239 100644 --- a/src/core/2/domains/tube/codac2_TubeEvaluation.h +++ b/src/core/2/domains/tube/codac2_TubeEvaluation.h @@ -46,7 +46,7 @@ namespace codac2 return *this; } - explicit operator T() const + operator T() const { return _tube->eval(_t); } @@ -74,8 +74,8 @@ namespace codac2 const Interval _t; Tube* _tube; - template - friend class Tube; + + friend class Tube; }; template @@ -111,8 +111,8 @@ namespace codac2 const Interval _t; const Tube* _tube; - template - friend class Tube; + + friend class Tube; }; } diff --git a/src/core/2/tools/codac2_isbaseof.h b/src/core/2/tools/codac2_isbaseof.h new file mode 100644 index 000000000..2ee56205b --- /dev/null +++ b/src/core/2/tools/codac2_isbaseof.h @@ -0,0 +1,21 @@ +#ifndef __CODAC2_ISBASEOF__ +#define __CODAC2_ISBASEOF__ + +// From https://stackoverflow.com/questions/32477691/is-base-of-of-generic-type +#include + +namespace detail +{ + template class C> + struct is_base_of_any_helper + { + template + std::true_type operator ()(const C*) const; + std::false_type operator()(...) const; + }; +} + +template class C, typename T> +using is_base_of_any = decltype(detail::is_base_of_any_helper{}(std::declval())); + +#endif \ No newline at end of file diff --git a/src/core/2/tools/codac2_tuples.h b/src/core/2/tools/codac2_tuples.h new file mode 100644 index 000000000..350c397b8 --- /dev/null +++ b/src/core/2/tools/codac2_tuples.h @@ -0,0 +1,19 @@ +#ifndef __CODAC2_TUPLES__ +#define __CODAC2_TUPLES__ + +#include + +template +bool are_all_members_the_same(std::index_sequence, const Tuple& left, const Tuple& right) +{ + return ((std::get(left).get() == std::get(right).get()) && ...); +} + +template +bool are_all_members_the_same(const Tuple&left, const Tuple& right) +{ + return are_all_members_the_same( + std::make_index_sequence::value>(), left, right); +} + +#endif \ No newline at end of file diff --git a/src/core/2/variables/codac2_Matrix.h b/src/core/2/variables/codac2_Matrix.h index bff4c3b8f..e0030d1d8 100644 --- a/src/core/2/variables/codac2_Matrix.h +++ b/src/core/2/variables/codac2_Matrix.h @@ -224,8 +224,6 @@ namespace codac2 *(f.data()+i) = std::fabs(*(x.data()+i)); return f; } - - using Matrix = Matrix_<>; /*class Matrix : public Matrix_<> { @@ -257,6 +255,9 @@ namespace codac2 : Matrix_<>(v) { } };*/ + + using Matrix = Matrix_<>; + } // namespace codac #endif \ No newline at end of file diff --git a/src/core/2/variables/codac2_Vector.h b/src/core/2/variables/codac2_Vector.h index 5aa75fe3c..33b67a066 100644 --- a/src/core/2/variables/codac2_Vector.h +++ b/src/core/2/variables/codac2_Vector.h @@ -163,8 +163,6 @@ namespace codac2 return x_; } - using Vector = Vector_<>; - /*class Vector : public Vector_<> { public: @@ -193,6 +191,8 @@ namespace codac2 };*/ + using Vector = Vector_<>; + } // namespace codac #endif \ No newline at end of file diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index edc516231..ca4ad47bb 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -183,12 +183,13 @@ ${CMAKE_CURRENT_SOURCE_DIR}/2/3rd/codac2_eigen.h ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_ContractorNetwork.cpp ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_ContractorNetwork.h - ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_Contractor.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_Contractor.h - ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_ContractorNode.cpp ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_ContractorNode.h - ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_DomainNode.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_DomainCaster.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_DomainCaster.h ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_DomainNode.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_PropagationSpan.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_PropagationSpan.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_Var.cpp ${CMAKE_CURRENT_SOURCE_DIR}/2/cn/codac2_Var.h ${CMAKE_CURRENT_SOURCE_DIR}/2/domains/codac2_Domain.h ${CMAKE_CURRENT_SOURCE_DIR}/2/domains/interval/codac2_Interval.cpp @@ -212,13 +213,32 @@ ${CMAKE_CURRENT_SOURCE_DIR}/2/domains/tube/codac2_TubeComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/2/domains/tube/codac2_TubeEvaluation.h ${CMAKE_CURRENT_SOURCE_DIR}/2/domains/paving/codac2_Paving.h + + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_arithmetic_ctc.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_arithmetic_ctc.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_Ctc.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcAction.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcAction.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcCN.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcCN.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcDeriv.h ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcDiffInclusion.cpp ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcDiffInclusion.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcDist.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcDist.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcInter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcInter.h ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcLinobs.cpp ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcLinobs.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcNoCross.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcNoCross.h ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcPaver.h - ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcInter.h - ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcCN.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcPolar.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcPolar.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcUnion.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_linear_ctc.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_linear_ctc.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/integration/codac2_AbstractDomain.cpp ${CMAKE_CURRENT_SOURCE_DIR}/2/integration/codac2_AbstractDomain.h ${CMAKE_CURRENT_SOURCE_DIR}/2/variables/codac2_Matrix.h @@ -228,9 +248,13 @@ ${CMAKE_CURRENT_SOURCE_DIR}/2/actions/codac2_Action.h ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcAction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/2/contractors/codac2_CtcAction.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/tools/codac2_isbaseof.h + ${CMAKE_CURRENT_SOURCE_DIR}/2/tools/codac2_tuples.h ) - set(SRC ${CODAC1_SRC} ${CODAC2_SRC}) + set(SRC ${CODAC1_SRC} + ${CODAC2_SRC} + ) ################################################################################ @@ -267,7 +291,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/2/domains/paving ${CMAKE_CURRENT_SOURCE_DIR}/2/integration/ ${CMAKE_CURRENT_SOURCE_DIR}/2/actions/ - ${CMAKE_CURRENT_SOURCE_DIR}/2/variables/) + ${CMAKE_CURRENT_SOURCE_DIR}/2/variables/ + ${CMAKE_CURRENT_SOURCE_DIR}/2/tools/) target_link_libraries(codac PUBLIC Ibex::ibex) diff --git a/src/core/contractors/static/codac_CtcUnion.h b/src/core/contractors/static/codac_CtcUnion.h index 47b9ff926..336162dbd 100644 --- a/src/core/contractors/static/codac_CtcUnion.h +++ b/src/core/contractors/static/codac_CtcUnion.h @@ -62,7 +62,7 @@ namespace codac template CtcUnion& operator|=(const C& c) { - assert(c.nb_var == nb_var()); + assert(c.nb_var == nb_var); _v_ctc.push_back(std::make_shared(c)); return *this; } diff --git a/src/core/functions/codac_TFunction.h b/src/core/functions/codac_TFunction.h index b768bef29..df4ebfb5c 100644 --- a/src/core/functions/codac_TFunction.h +++ b/src/core/functions/codac_TFunction.h @@ -71,7 +71,7 @@ namespace codac const IntervalVector eval_vector(const IntervalVector& x1, const IntervalVector& x2) const; template - const IntervalVector eval_vector(const IntervalVector& x1, const IntervalVector& x2, FirstArg& xi, Args&... xs) // recursive variadic function + const IntervalVector eval_vector(const IntervalVector& x1, const IntervalVector& x2, const FirstArg& xi, const Args&... xs) // recursive variadic function { IntervalVector x_ = cart_prod(x1,x2,xi); if constexpr(sizeof...(xs) > 0) diff --git a/tests/catch/catch_interval.hpp b/tests/catch/catch_interval.hpp index b1ec695a4..3b2223edd 100644 --- a/tests/catch/catch_interval.hpp +++ b/tests/catch/catch_interval.hpp @@ -27,6 +27,7 @@ #include "codac_ConvexPolygon.h" #include "codac_TubeVector.h" #include "codac_Slice.h" +#include "codac2_IntervalVector.h" namespace Catch { @@ -113,6 +114,32 @@ namespace Catch return !operator ==(rhs, lhs); } + // Codac2 part + + explicit ApproxIntvVector(codac2::IntervalVector value) : + m_value(codac2::to_codac1(value)) + {} + + friend bool operator ==(codac2::IntervalVector lhs, ApproxIntvVector const& rhs) + { + return operator ==(codac2::to_codac1(lhs), rhs); + } + + friend bool operator ==(ApproxIntvVector const& lhs, codac2::IntervalVector rhs) + { + return operator ==(codac2::to_codac1(rhs), lhs); + } + + friend bool operator !=(codac2::IntervalVector lhs, ApproxIntvVector const& rhs) + { + return !operator ==(codac2::to_codac1(lhs), rhs); + } + + friend bool operator !=(ApproxIntvVector const& lhs, codac2::IntervalVector rhs) + { + return !operator ==(codac2::to_codac1(rhs), lhs); + } + std::string toString() const { std::ostringstream oss; diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt index e33acb3cb..bb0527fd1 100644 --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -6,10 +6,12 @@ set(TESTS_NAME codac-tests-core) list(APPEND SRC_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_tubes.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_intervalvector.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_intervalmatrix.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_tubes_templated_types.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_tubes.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_intervalvector.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_intervalmatrix.cpp +# ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_tubes_templated_types.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_cn.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tests_codac2_CtcUnion.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests_predefined_tubes.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests_predefined_tubes.h diff --git a/tests/core/tests_codac2_CtcUnion.cpp b/tests/core/tests_codac2_CtcUnion.cpp new file mode 100644 index 000000000..fa2471d2b --- /dev/null +++ b/tests/core/tests_codac2_CtcUnion.cpp @@ -0,0 +1,18 @@ +#include "catch_interval.hpp" +#include "vibes.h" + +#include "codac2_CtcUnion.h" + +using namespace Catch; +using namespace Detail; +using namespace std; +using namespace codac2; + +TEST_CASE("Tests for CtcUnion") +{ + SECTION("Test1") + { + CtcUnion cu; + + } +} \ No newline at end of file diff --git a/tests/core/tests_codac2_cn.cpp b/tests/core/tests_codac2_cn.cpp new file mode 100644 index 000000000..1e1b25003 --- /dev/null +++ b/tests/core/tests_codac2_cn.cpp @@ -0,0 +1,128 @@ +#include "catch_interval.hpp" +#include "vibes.h" + +#include "codac2_ContractorNetwork.h" + +using namespace Catch; +using namespace Detail; +using namespace std; +using namespace codac2; + +TEST_CASE("Tests for CN") +{ + SECTION("PropagationSpan for two Intervals") + { + // Full contraction case + { + Interval a(2,4), b(3,5); + auto span = propagspan_from_contraction(a,b); + CHECK(span != nullptr); + auto span_cast = std::dynamic_pointer_cast>(span); + CHECK(span_cast); + CHECK(span_cast->_x == &b); + CHECK(!span_cast->intersects(std::make_shared>(&a))); + CHECK(span_cast->intersects(std::make_shared>(&b))); + } + + // No contraction case + { + Interval a(2,4), b(2,4); + auto span = propagspan_from_contraction(a,b); + CHECK(span == nullptr); + } + } + + SECTION("PropagationSpan for two Interval variables") + { + // Full contraction case + { + Var a(2,4), b(3,5); + auto span = propagspan_from_contraction(a,b); + CHECK(span != nullptr); + auto span_cast = std::dynamic_pointer_cast>(span); + CHECK(span_cast); + CHECK(span_cast->_x == &b); + CHECK(!span_cast->intersects(std::make_shared>(&a))); + CHECK(span_cast->intersects(std::make_shared>(&b))); + } + + // No contraction case + { + Var a(2,4), b(2,4); + auto span = propagspan_from_contraction(a,b); + CHECK(span == nullptr); + } + } + + SECTION("PropagationSpan for two IntervalVectors") + { + // Full contraction case + { + IntervalVector a({{2,4},{12,14}}), b({{3,5},{13,15}}); + auto span = propagspan_from_contraction(a,b); + CHECK(span != nullptr); + auto span_cast = std::dynamic_pointer_cast>(span); + CHECK(span_cast); + CHECK(span_cast->_x == &b); + CHECK(span_cast->_indices == vector({0,1})); + CHECK(!span_cast->intersects(std::make_shared>(&a))); + CHECK(span_cast->intersects(std::make_shared>(&b))); + } + + // Partial contraction case + { + IntervalVector a({{2,4},{12,14}}), b({{2,4},{13,15}}); + auto span = propagspan_from_contraction(a,b); + CHECK(span != nullptr); + auto span_cast = std::dynamic_pointer_cast>(span); + CHECK(span_cast); + CHECK(span_cast->_x == &b); + CHECK(span_cast->_indices == vector({1})); + CHECK(!span_cast->intersects(std::make_shared>(&a))); + CHECK(span_cast->intersects(std::make_shared>(&b))); + } + + // No contraction case + { + IntervalVector a({{2,4},{12,14}}), b({{2,4},{12,14}}); + auto span = propagspan_from_contraction(a,b); + CHECK(span == nullptr); + } + } + + SECTION("PropagationSpan for two IntervalVector variables") + { + // Full contraction case + { + Var a({{2,4},{12,14}}), b({{3,5},{13,15}}); + auto span = propagspan_from_contraction(a,b); + CHECK(span != nullptr); + auto span_cast = std::dynamic_pointer_cast>(span); + CHECK(span_cast); + CHECK(span_cast->_x == &b); + CHECK(span_cast->_indices == vector({0,1})); + CHECK(!span_cast->intersects(std::make_shared>(&a))); + CHECK(span_cast->intersects(std::make_shared>(&b))); + } + + // Partial contraction case + { + Var a({{2,4},{12,14}}), b({{2,4},{13,15}}); + auto span = propagspan_from_contraction(a,b); + CHECK(span != nullptr); + auto span_cast = std::dynamic_pointer_cast>(span); + CHECK(span_cast); + CHECK(span_cast->_x == &b); + CHECK(span_cast->_indices == vector({1})); + CHECK(!span_cast->intersects(std::make_shared>(&a))); + CHECK(span_cast->intersects(std::make_shared>(&b))); + } + + // No contraction case + { + Var a({{2,4},{12,14}}), b({{2,4},{12,14}}); + auto span = propagspan_from_contraction(a,b); + CHECK(span == nullptr); + } + } +} \ No newline at end of file diff --git a/tests/core/tests_codac2_intervalvector.cpp b/tests/core/tests_codac2_intervalvector.cpp index 965586a96..67ae79222 100644 --- a/tests/core/tests_codac2_intervalvector.cpp +++ b/tests/core/tests_codac2_intervalvector.cpp @@ -177,7 +177,8 @@ TEST_CASE("Tests from IBEX IntervalVector") SECTION("subvector06") { - CHECK(IntervalVector::empty_set(3).subvector(1,2).is_empty()); + IntervalVector x = IntervalVector::empty_set(3); + CHECK(x.subvector(1,2).is_empty()); } SECTION("cart_prod01") @@ -703,7 +704,8 @@ TEST_CASE("Tests from IBEX IntervalVector::diff") SECTION("compl02") { // complementary of an empty box = (-oo,oo)x...(-oo,oo) - auto c = IntervalVector::empty_set(2).complementary(); + IntervalVector x = IntervalVector::empty_set(2); + auto c = x.complementary(); CHECK(c.size()==1); CHECK(c.front().size()==2); CHECK(c.front()[0]==Interval::all_reals()); diff --git a/tests/core/tests_codac2_tubes.cpp b/tests/core/tests_codac2_tubes.cpp index 18bc6659d..d40d3e708 100644 --- a/tests/core/tests_codac2_tubes.cpp +++ b/tests/core/tests_codac2_tubes.cpp @@ -6,16 +6,14 @@ #define protected public #include "codac2_TDomain.h" -#include "codac_predef_values.h" +//#include "codac_predef_values.h" #include "codac2_Tube.h" #include "codac2_CtcDiffInclusion.h" using namespace Catch; using namespace Detail; using namespace std; -using namespace ibex; using namespace codac2; -using codac::oo; Tube return_a_tube() { @@ -24,7 +22,7 @@ Tube return_a_tube() IntervalVector(3,Interval(-1.5,1))); } -TEST_CASE("Test codac2::tubes") +TEST_CASE("Test tubes") { SECTION("Test TDomain") { @@ -283,22 +281,22 @@ TEST_CASE("Test codac2::tubes") CHECK(x.codomain() == IntervalVector(3, Interval(-10,10))); // TubeComponent - CHECK(x[0].codomain() == Interval(-10,10)); - CHECK(x[0].t0_tf() == Interval(0,1)); - CHECK(x[0].tdomain() == tdomain); - x[0].set(Interval(-20,20)); - CHECK(x[0].codomain() == Interval(-20,20)); - CHECK(x.codomain() == IntervalVector({Interval(-20,20),Interval(-10,10),Interval(-10,10)})); - x[1] = x[0]; - CHECK(x[1].codomain() == Interval(-20,20)); - CHECK(x.codomain() == IntervalVector({Interval(-20,20),Interval(-20,20),Interval(-10,10)})); + // removed: CHECK(x[0].codomain() == Interval(-10,10)); + // removed: CHECK(x[0].t0_tf() == Interval(0,1)); + // removed: CHECK(x[0].tdomain() == tdomain); + // removed: x[0].set(Interval(-20,20)); + // removed: CHECK(x[0].codomain() == Interval(-20,20)); + // removed: CHECK(x.codomain() == IntervalVector({Interval(-20,20),Interval(-10,10),Interval(-10,10)})); + // removed: x[1] = x[0]; + // removed: CHECK(x[1].codomain() == Interval(-20,20)); + // removed: CHECK(x.codomain() == IntervalVector({Interval(-20,20),Interval(-20,20),Interval(-10,10)})); // Eval CHECK(tdomain->nb_tubes() == 1); - CHECK(static_cast(x(Interval(-oo,oo))) == IntervalVector(3)); - CHECK(static_cast(x(Interval(-1,1))) == IntervalVector(3)); - CHECK(static_cast(x(tdomain->t0_tf())) == x.codomain()); - CHECK(static_cast(x(-42.)) == IntervalVector(3)); + CHECK(x(Interval(-oo,oo)) == IntervalVector(3)); + CHECK(x(Interval(-1,1)) == IntervalVector(3)); + CHECK(x(tdomain->t0_tf()) == x.codomain()); + CHECK(x(-42.) == IntervalVector(3)); // Eval: affectation at scalar t CHECK(tdomain->nb_tslices() == 10); @@ -403,14 +401,14 @@ TEST_CASE("Test codac2::tubes") CHECK(x.size() == 2); CHECK(u.size() == 2); - codac::TFunction tf("x[2]", "u[2]", "(sin(x[1]) ; -sin(x[0]))"); - CtcDiffInclusion ctc_diffincl(tf); - ctc_diffincl.contract(x,u); + //codac::TFunction tf("x[2]", "u[2]", "(sin(x[1]) ; -sin(x[0]))"); + //CtcDiffInclusion ctc_diffincl(tf); + //ctc_diffincl.contract(x,u); //vibes::beginDrawing(); - codac::TubeVector x_codac1 = to_codac1(x); // may take time - codac::Tube xi_codac1 = to_codac1(x)[1]; // may take time + //codac::TubeVector x_codac1 = to_codac1(x); // may take time + //codac::Tube xi_codac1 = to_codac1(x)[1]; // may take time //codac::VIBesFigTube fig("Tube"); //fig.set_properties(100, 100, 600, 300); @@ -443,7 +441,7 @@ TEST_CASE("Test codac2::tubes") IntervalVector u({{0,0.1},{0,0.1}}); Interval t(5.); //cout << f.eval_vector(t,x,u) << endl; - CHECK(f.eval_vector(t,x,u) == ApproxIntvVector(IntervalVector({{7, 8.100000000000002},{10, 11.10000000000001}}))); + CHECK(f.eval_vector(t,to_codac1(x),to_codac1(u)) == ApproxIntvVector(IntervalVector({{7, 8.100000000000002},{10, 11.10000000000001}}))); } } @@ -489,20 +487,20 @@ TEST_CASE("Test codac2::tubes") { codac::Tube codac1(Interval(0,10),1.,Interval(-3,6)); auto tdomain = create_tdomain(Interval(0,10),1.,true); // with gates - codac2::Tube codac2(tdomain, Interval(-3,6)); + Tube codac2(tdomain, Interval(-3,6)); CHECK(to_codac1(codac2) == codac1); CHECK(to_codac2(codac1) == codac2); CHECK(to_codac1(to_codac2(codac1)) == codac1); CHECK(to_codac2(to_codac1(codac2)) == codac2); - codac::TubeVector codac1_vector(Interval(0,10),1.,IntervalVector({{-1,2},{6,8}})); - codac2::Tube codac2_vector(tdomain, IntervalVector({{-1,2},{6,8}})); + codac::TubeVector codac1_vector(Interval(0,10),1.,codac::IntervalVector({{-1,2},{6,8}})); + Tube codac2_vector(tdomain, IntervalVector({{-1,2},{6,8}})); codac1_vector.set({{1.2,1.3},{6.8,6.9}}, 0.58); codac2_vector.set({{1.2,1.3},{6.8,6.9}}, 0.58); codac1_vector.set({{1.6},{7.2}}, 10.); codac2_vector.set({{1.6},{7.2}}, 10.); CHECK(tdomain->t0_tf().ub() == 10.); - CHECK(codac1_vector(0.58) == IntervalVector({{1.2,1.3},{6.8,6.9}})); + CHECK(codac1_vector(0.58) == codac::IntervalVector({{1.2,1.3},{6.8,6.9}})); CHECK(IntervalVector(codac2_vector(0.58)) == IntervalVector({{1.2,1.3},{6.8,6.9}})); CHECK(to_codac1(codac2_vector) == codac1_vector); @@ -511,18 +509,18 @@ TEST_CASE("Test codac2::tubes") CHECK(to_codac2(to_codac1(codac2_vector)) == codac2_vector); codac::TubeVector to_codac1_codac2_vector = to_codac1(codac2_vector); - codac2::Tube to_codac2_codac1_vector = to_codac2(codac1_vector); + Tube to_codac2_codac1_vector = to_codac2(codac1_vector); // t=0.58 - CHECK(to_codac1_codac2_vector(ibex::previous_float(0.58)) == IntervalVector({{-1,2},{6,8}})); - CHECK(to_codac1_codac2_vector(0.58) == IntervalVector({{1.2,1.3},{6.8,6.9}})); - CHECK(to_codac1_codac2_vector(ibex::next_float(0.58)) == IntervalVector({{-1,2},{6,8}})); + CHECK(to_codac1_codac2_vector(ibex::previous_float(0.58)) == codac::IntervalVector({{-1,2},{6,8}})); + CHECK(to_codac1_codac2_vector(0.58) == codac::IntervalVector({{1.2,1.3},{6.8,6.9}})); + CHECK(to_codac1_codac2_vector(ibex::next_float(0.58)) == codac::IntervalVector({{-1,2},{6,8}})); CHECK(IntervalVector(to_codac2_codac1_vector(ibex::previous_float(0.58))) == IntervalVector({{-1,2},{6,8}})); CHECK(IntervalVector(to_codac2_codac1_vector(0.58)) == IntervalVector({{1.2,1.3},{6.8,6.9}})); CHECK(IntervalVector(to_codac2_codac1_vector(ibex::next_float(0.58))) == IntervalVector({{-1,2},{6,8}})); // t=10 - CHECK(to_codac1_codac2_vector(ibex::previous_float(10.)) == IntervalVector({{-1,2},{6,8}})); - CHECK(to_codac1_codac2_vector(10.) == IntervalVector({{1.6},{7.2}})); - CHECK(to_codac1_codac2_vector(ibex::next_float(10.)) == IntervalVector(2)); + CHECK(to_codac1_codac2_vector(ibex::previous_float(10.)) == codac::IntervalVector({{-1,2},{6,8}})); + CHECK(to_codac1_codac2_vector(10.) == codac::IntervalVector({{1.6},{7.2}})); + CHECK(to_codac1_codac2_vector(ibex::next_float(10.)) == codac::IntervalVector(2)); CHECK(IntervalVector(to_codac2_codac1_vector(ibex::previous_float(10.))) == IntervalVector({{-1,2},{6,8}})); CHECK(IntervalVector(to_codac2_codac1_vector(10.)) == IntervalVector({{1.6},{7.2}})); CHECK(IntervalVector(to_codac2_codac1_vector(ibex::next_float(10.))) == IntervalVector(2)); @@ -534,7 +532,7 @@ TEST_CASE("Test codac2::tubes") Tube x(tdomain, Interval(-10,10)); CHECK(x.codomain() == Interval(-10,10)); - std::list::iterator it = tdomain->tslices().begin(); + std::list::iterator it = tdomain->tslices().begin(); CHECK(it->t0_tf() == Interval(0)); CHECK(x(it).codomain() == Interval(-10,10)); it++; @@ -568,7 +566,7 @@ TEST_CASE("Test codac2::tubes") Tube y(tdomain, Interval(2.)), x1(tdomain, Interval(-1,1)), x2(tdomain, Interval(1)); Tube cx1(x1), cx2(x2); // copy - for(std::list::iterator it = cx1.tdomain()->tslices().begin(); + for(std::list::iterator it = cx1.tdomain()->tslices().begin(); it != cx1.tdomain()->tslices().end(); ++it) { Interval ix1 = cx1(it).codomain(), ix2 = cx2(it).codomain(); @@ -593,7 +591,7 @@ TEST_CASE("Test codac2::tubes") { auto tdomain = create_tdomain(Interval(0,5), 0.1, true); Tube a(tdomain, TFunction("10*cos(t)+t")); - codac::Tube a_codac1 = codac2::to_codac1(a); + codac::Tube a_codac1 = to_codac1(a); //vibes::beginDrawing(); //codac::VIBesFigTube fig("Tube"); //fig.set_properties(100, 100, 600, 300); diff --git a/tests/core/tests_codac2_tubes_templated_types.cpp b/tests/core/tests_codac2_tubes_templated_types.cpp index a27f1a989..45cd7dd88 100644 --- a/tests/core/tests_codac2_tubes_templated_types.cpp +++ b/tests/core/tests_codac2_tubes_templated_types.cpp @@ -22,11 +22,11 @@ TEST_CASE("Test codac2::tubes templated") vector>*> v; for(const auto& s : a) v.push_back(&s); - CHECK(v[0]->t0_tf() == Interval(-codac2::oo,2.3)); + CHECK(v[0]->t0_tf() == Interval(-oo,2.3)); CHECK(v[0]->codomain() == (IntervalMatrix_<2,3>())); CHECK(v[1]->t0_tf() == Interval(2.3)); CHECK(v[1]->codomain() == (IntervalMatrix_<2,3>({{1.,2.,3.},{4.,5.,6.}}))); - CHECK(v[2]->t0_tf() == Interval(2.3,codac2::oo)); + CHECK(v[2]->t0_tf() == Interval(2.3,oo)); CHECK(v[2]->codomain() == (IntervalMatrix_<2,3>())); } } \ No newline at end of file