codac 2.0.0
Loading...
Searching...
No Matches
codac2_CtcUnion.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include <tuple>
13#include <type_traits>
14#include "codac2_CtcWrapper.h"
15#include "codac2_Collection.h"
17
18namespace codac2
19{
20 template<typename... X>
21 class CtcUnion : public Ctc<CtcUnion<X...>,X...>
22 {
23 public:
24
25 explicit CtcUnion(Index n)
26 : Ctc<CtcUnion<X...>,X...>(n)
27 {
28 if constexpr(std::is_same_v<X...,Interval>)
29 assert_release(n == 1);
30 }
31
32 template<typename C>
33 requires (IsCtcBaseOrPtr<C,X...> && !std::is_same_v<CtcUnion<X...>,C>)
34 CtcUnion(const C& c)
35 : Ctc<CtcUnion<X...>,X...>(size_of(c)), _ctcs(c)
36 { }
37
38 template<typename... C>
39 requires (IsCtcBaseOrPtr<C,X...> && ...)
40 CtcUnion(const C&... c)
41 : Ctc<CtcUnion<X...>,X...>(size_first_item(c...)), _ctcs(c...)
42 {
43 assert_release(all_same_size(c...));
44 }
45
46 CtcUnion(const Collection<CtcBase<X...>>& ctcs)
47 : Ctc<CtcUnion<X...>,X...>(ctcs.front()->size()), _ctcs(ctcs)
48 {
49 for(const auto& ci : _ctcs)
50 {
51 (void)ci;
52 assert_release(ci->size() == this->size());
53 }
54 }
55
56 template<typename C>
57 requires IsCtcBaseOrPtr<C,X...>
58 CtcUnion(std::initializer_list<C> ctcs)
59 : CtcUnion(Collection<CtcBase<X...>>(ctcs))
60 { }
61
62 size_t nb() const
63 {
64 return _ctcs.size();
65 }
66
67 void contract(X&... x) const
68 {
69 const auto input = std::tuple<X...>(x...);
70
71 auto result = input;
72 std::apply([](auto&... xi)
73 {
74 (xi.set_empty(), ...);
75 }, result);
76
77 auto accumulate_union = [&]<std::size_t... I>(const std::tuple<X...>& y, std::index_sequence<I...>)
78 {
79 ((std::get<I>(result) |= std::get<I>(y)), ...);
80 };
81
82 for(const auto& ci : _ctcs)
83 {
84 auto saved = input;
85
86 std::apply([&](auto&... xi)
87 {
88 ci->contract(xi...);
89 }, saved);
90
91 accumulate_union(saved, std::index_sequence_for<X...>{});
92
93 // Each contractor is contractant, hence every remaining branch
94 // can only return a subset of input. Once the accumulated union
95 // has reached input, the final result is already known.
96 if(result == input)
97 return;
98 }
99
100 std::tie(x...) = result;
101 }
102
103 template<typename C>
104 requires IsCtcBaseOrPtr<C,X...>
105 CtcUnion<X...>& operator|=(const C& c)
106 {
107 assert_release(size_of(c) == this->size());
108 _ctcs.push_back(c);
109 return *this;
110 }
111
112 protected:
113
114 Collection<CtcBase<X...>> _ctcs;
115 };
116
117 template <>
118 class CtcUnion<> : public CtcUnion<IntervalVector>
119 { };
120
121 template<typename Tuple>
122 struct CtcUnionType;
123
124 template<typename... T>
125 struct CtcUnionType<std::tuple<T...>> {
126 using Ctc = CtcUnion<T...>;
127 };
128
129 template<typename C1,typename C2>
130 typename CtcUnionType<typename C1::ContractedTypes>::Ctc operator|(const C1& c1, const C2& c2)
131 {
132 return { c1, c2 };
133 }
134
135 template<typename C1,typename C2>
136 typename CtcUnionType<typename C1::ContractedTypes>::Ctc operator|(const std::shared_ptr<C1>& c1, const std::shared_ptr<C2>& c2)
137 {
138 return { c1, c2 };
139 }
140
141 template<typename C1,typename C2>
142 typename CtcUnionType<typename C1::ContractedTypes>::Ctc operator|(const std::shared_ptr<C1>& c1, const C2& c2)
143 {
144 return { c1, c2 };
145 }
146
147 template<typename C1,typename C2>
148 typename CtcUnionType<typename C1::ContractedTypes>::Ctc operator|(const C1& c1, const std::shared_ptr<C2>& c2)
149 {
150 return { c1, c2 };
151 }
152
153 template<typename C2>
154 requires std::is_base_of_v<CtcBase<IntervalVector>,C2>
155 inline CtcUnion<IntervalVector> operator|(const IntervalVector& c1, const C2& c2)
156 {
157 assert_release(c1.size() == c2.size());
158 return CtcUnion<IntervalVector>(CtcWrapper(c1),c2);
159 }
160
161 template<typename C1>
162 requires std::is_base_of_v<CtcBase<IntervalVector>,C1>
163 inline CtcUnion<IntervalVector> operator|(const C1& c1, const IntervalVector& c2)
164 {
165 assert_release(c1.size() == c2.size());
166 return CtcUnion<IntervalVector>(c1,CtcWrapper(c2));
167 }
168
169 // Template deduction guides
170 CtcUnion(Index) -> CtcUnion<IntervalVector>;
171
172 template<typename... C>
173 requires (IsCtcBaseOrPtr<C,IntervalVector> && ...)
174 CtcUnion(const C&...) -> CtcUnion<IntervalVector>;
175
176 template<typename C>
177 CtcUnion(std::initializer_list<C>) -> CtcUnion<IntervalVector>;
178}
Definition codac2_OctaSym.h:21
Eigen::Matrix< Interval,-1, 1 > IntervalVector
Alias for a dynamic-size column vector of intervals.
Definition codac2_IntervalVector.h:25