15namespace sequoia::physics
17 using namespace maths;
20 struct associated_displacement_space;
35 inline constexpr bool identifies_as_unit_v{
38 requires std::convertible_to<typename T::is_unit, std::true_type>;
44 = identifies_as_unit_v<T>
45 &&
requires {
typename T::validator_type; };
59namespace sequoia::meta
61 template<
class T,
class U>
62 requires (!std::is_same_v<T, U>)
63 struct type_comparator<
maths::dual<T>, U> : std::bool_constant<type_name<T>() < type_name<U>()>
66 template<
class T,
class U>
67 requires (!std::is_same_v<T, U>) && (!physics::is_associated_displacement_space_v<T>) && (!physics::is_associated_displacement_space_v<U>)
68 struct type_comparator<T, maths::dual<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
71 template<
class T,
class U>
72 struct type_comparator<maths::dual<T>, maths::dual<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
75 template<class T, class U>
76 requires (!maths::is_dual_v<U>)
77 struct type_comparator<physics::associated_displacement_space<T>, U> : std::bool_constant<type_name<T>() < type_name<U>()>
80 template<class T, class U>
81 requires (!maths::is_dual_v<T>)
82 struct type_comparator<T, physics::associated_displacement_space<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
85 template<class T, class U>
86 requires (!std::is_same_v<physics::associated_displacement_space<T>, U>) && (!physics::is_associated_displacement_space_v<U>)
87 struct type_comparator<physics::associated_displacement_space<T>, maths::dual<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
90 template<class T, class U>
91 requires (!std::is_same_v<T, physics::associated_displacement_space<U>>)
92 struct type_comparator<maths::dual<T>, physics::associated_displacement_space<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
95 template<class T, class U>
96 requires (!std::is_same_v<physics::associated_displacement_space<T>, U>)
97 struct type_comparator<maths::dual<physics::associated_displacement_space<T>>, U>
98 : std::bool_constant<type_name<T>() < type_name<U>()>
101 template<class T, class U>
102 requires (!std::is_same_v<T, physics::associated_displacement_space<U>>) && (!physics::is_associated_displacement_space_v<T>)
103 struct type_comparator<T, maths::dual<physics::associated_displacement_space<U>>>
104 : std::bool_constant<type_name<T>() < type_name<U>()>
107 template<class T, class U>
108 struct type_comparator<physics::associated_displacement_space<T>, physics::associated_displacement_space<U>>
109 : std::bool_constant<type_name<T>() < type_name<U>()>
112 template<class T, class U>
113 struct type_comparator<maths::dual<physics::associated_displacement_space<T>>, maths::dual<physics::associated_displacement_space<U>>>
114 : std::bool_constant<type_name<T>() < type_name<U>()>
119 struct type_comparator<T, maths::dual<T>> : std::true_type
123 struct type_comparator<maths::dual<T>, T> : std::false_type
127 struct type_comparator<T, physics::associated_displacement_space<T>> : std::true_type
131 struct type_comparator<physics::associated_displacement_space<T>, T> : std::false_type
135 struct type_comparator<T, maths::dual<physics::associated_displacement_space<T>>> : std::true_type
139 struct type_comparator<maths::dual<physics::associated_displacement_space<T>>, T> : std::false_type
143 struct type_comparator<physics::associated_displacement_space<T>, maths::dual<T>> : std::true_type
147 struct type_comparator<maths::dual<T>, physics::associated_displacement_space<T>> : std::false_type
151 struct type_comparator<maths::dual<T>, maths::dual<physics::associated_displacement_space<T>>> : std::true_type
155 struct type_comparator<maths::dual<physics::associated_displacement_space<T>>, maths::dual<T>> : std::false_type
159namespace sequoia::physics::impl
161 using namespace maths;
163 template<class T, int I>
164 struct type_counter {};
168 struct count_and_combine {};
170 template<class... Ts>
171 using count_and_combine_t = count_and_combine<Ts...>::type;
174 struct count_and_combine<direct_product<>>
176 using type = direct_product<>;
180 struct count_and_combine<T>
182 using type = direct_product<type_counter<T, 1>>;
186 struct count_and_combine<direct_product<T>>
188 using type = direct_product<type_counter<T, 1>>;
191 template<class T, class... Ts>
192 struct count_and_combine<direct_product<T, Ts...>>
193 : count_and_combine<direct_product<Ts...>, count_and_combine_t<T>>
196 template<class T, class... Us, int... Is>
197 struct count_and_combine<direct_product<T>, direct_product<type_counter<Us, Is>...>>
198 : count_and_combine<T, direct_product<type_counter<Us, Is>...>>
201 template<class T, class... Ts, class... Us, int... Is>
202 requires (sizeof...(Ts) > 0)
203 struct count_and_combine<direct_product<T, Ts...>, direct_product<type_counter<Us, Is>...>>
204 : count_and_combine<direct_product<Ts...>, count_and_combine_t<T, direct_product<type_counter<Us, Is>...>>>
207 template<class S, class T, int I, class... Ts, int... Is>
208 requires (!is_direct_product_v<S> && !is_dual_v<S> && !std::is_same_v<S, T> && !std::is_same_v<S, associated_displacement_space<T>>)
209 struct count_and_combine<S, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
211 using type = direct_product<type_counter<S, 1>, type_counter<T, I>, type_counter<Ts, Is>...>;
214 template<class S, class T, int I, class... Ts, int... Is>
215 requires (!std::is_same_v<S, T> && !std::is_same_v<S, dual_of_t<T>> && !std::is_same_v<S, associated_displacement_space<T>> && !std::is_same_v<S, dual_of_t<associated_displacement_space<T>>> && !std::is_same_v<S, associated_displacement_space<dual_of_t<T>>>
216 && !std::is_same_v<T, dual_of_t<S>> && !std::is_same_v<T, associated_displacement_space<S>> && !std::is_same_v<T, dual_of_t<associated_displacement_space<S>>> && !std::is_same_v<T, associated_displacement_space<dual_of_t<S>>>)
217 struct count_and_combine<dual<S>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
219 using type = direct_product<type_counter<dual<S>, 1>, type_counter<T, I>, type_counter<Ts, Is>...>;
222 template<class T, int I, class... Ts, int... Is>
223 struct count_and_combine<T, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
225 using type = direct_product<type_counter<T, I+1>, type_counter<Ts, Is>...>;
228 template<class T, int I, class... Ts, int... Is>
229 struct count_and_combine<dual<T>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
231 using type = direct_product<type_counter<T, I-1>, type_counter<Ts, Is>...>;
238 template<class T, int I, class... Ts, int... Is>
239 struct count_and_combine<associated_displacement_space<T>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
241 using type = direct_product<type_counter<associated_displacement_space<T>, I+1>, type_counter<Ts, Is>...>;
245 template<class T, int I, class... Ts, int... Is>
246 struct count_and_combine<dual<associated_displacement_space<T>>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
248 using type = direct_product<type_counter<associated_displacement_space<T>, I-1>, type_counter<Ts, Is>...>;
252 template<class T, int I, class... Ts, int... Is>
253 struct count_and_combine<dual<T>, direct_product<type_counter<associated_displacement_space<T>, I>, type_counter<Ts, Is>...>>
255 using type = direct_product<type_counter<associated_displacement_space<T>, I-1>, type_counter<Ts, Is>...>;
259 template<class T, int I, class... Ts, int... Is>
260 struct count_and_combine<dual<associated_displacement_space<T>>, direct_product<type_counter<dual<T>, I>, type_counter<Ts, Is>...>>
262 using type = direct_product<type_counter<dual<associated_displacement_space<T>>, I+1>, type_counter<Ts, Is>...>;
271 template<class... Ts>
272 using unpack_t = unpack<Ts...>::type;
274 template<class T, int I>
276 struct unpack<type_counter<T, I>> : unpack<type_counter<T, I - 1>, direct_product<T>>
279 template<class T, int I>
281 struct unpack<type_counter<T, I>> : unpack<type_counter<T, I + 1>, direct_product<dual<T>>>
284 template<class T, int I, class... Ts>
286 struct unpack<type_counter<T, I>, direct_product<Ts...>> : unpack<type_counter<T, I - 1>, direct_product<T, Ts...>>
289 template<class T, int I, class... Ts>
291 struct unpack<type_counter<T, I>, direct_product<Ts...>> : unpack<type_counter<T, I + 1>, direct_product<dual<T>, Ts...>>
294 template<class T, class... Ts>
295 struct unpack<type_counter<T, 0>, direct_product<Ts...>>
297 using type = direct_product<Ts...>;
300 template<class... Ts, int... Is>
301 struct unpack<direct_product<type_counter<Ts, Is>...>>
302 : meta::flatten<direct_product<unpack_t<type_counter<Ts, Is>>...>>
307 struct potentially_prunable : std::false_type {};
310 inline constexpr bool potentially_prunable_v{potentially_prunable<T>::value};
313 struct potentially_prunable<type_counter<T, 0>> : std::true_type
317 template<class T, class Arena, int I>
319 struct potentially_prunable<type_counter<euclidean_vector_space<T, 1, Arena>, I>> : std::true_type
323 template<class T, class Arena, int I>
325 struct potentially_prunable<type_counter<dual<euclidean_vector_space<T, 1, Arena>>, I>> : std::true_type
329 template<class T, class Arena, int I>
331 struct potentially_prunable<type_counter<euclidean_half_space<T, Arena>, I>> : std::true_type
335 template<class T, class Arena, int I>
337 struct potentially_prunable<type_counter<dual<euclidean_half_space<T, Arena>>, I>> : std::true_type
341 template<physics::physical_unit U, int I>
342 requires std::derived_from<U, no_unit_t> && (I != 0)
343 struct potentially_prunable<type_counter<U, I>> : std::true_type
348 struct not_potentially_prunable : std::negation<potentially_prunable<T>> {};
354 template<class... Ts>
355 using reduce_t = reduce<Ts...>::type;
357 template<physical_unit U>
358 struct reduce<direct_product<type_counter<U, 0>>>
360 using type = direct_product<no_unit_t>;
363 template<physical_unit U, int I>
364 requires std::derived_from<U, no_unit_t> && (I > 0)
365 struct reduce<direct_product<type_counter<U, I>>>
367 using type = direct_product<U>;
370 template<physics::physical_unit... Ts, int... Is>
371 struct reduce<direct_product<type_counter<Ts, Is>...>>
373 using type = unpack_t<meta::filter_by_trait_t<direct_product<type_counter<Ts, Is>...>, not_potentially_prunable>>;
376 template<convex_space... Ts, int... Is>
377 struct reduce<direct_product<type_counter<Ts, Is>...>>
382 constexpr static bool anyOfNotReducibleFreeModule {(( free_module<Ts> && !potentially_prunable_v<type_counter<Ts, Is>>) || ...)};
383 constexpr static bool anyOfNotReducibleHalfLine {(( is_non_negative_orthant_v<Ts> && !potentially_prunable_v<type_counter<Ts, Is>>) || ...)};
384 constexpr static bool allOfNotReducibleOrNotFreeModule{((!free_module<Ts> || !potentially_prunable_v<type_counter<Ts, Is>>) && ...)};
385 constexpr static bool allOfNotReducibleOrNotHalfLine {((!is_non_negative_orthant_v<Ts> || !potentially_prunable_v<type_counter<Ts, Is>>) && ...)};
387 using filtered_t = meta::filter_by_trait_t<direct_product<type_counter<Ts, Is>...>, not_potentially_prunable>;
389 using unpacked_t = unpack_t<filtered_t>;
391 constexpr static bool anyFreeModule{(free_module<Ts> || ...)};
396 direct_product<euclidean_vector_space<std::common_type_t<commutative_ring_type_of_t<Ts>...>, 1, std::common_type_t<arena_type_of_t<Ts>...>>>,
397 direct_product<euclidean_half_space<std::common_type_t<commutative_ring_type_of_t<Ts>...>, std::common_type_t<arena_type_of_t<Ts>...>>>
401 = std::conditional_t<
402 anyOfNotReducibleFreeModule || (allOfNotReducibleOrNotFreeModule && (anyOfNotReducibleHalfLine || allOfNotReducibleOrNotHalfLine)),
404 meta::merge_t<unpacked_t, root_space_t, meta::type_comparator>
412 template<class... Ts>
413 using simplify_t = simplify<Ts...>::type;
415 template<class... Ts>
416 struct simplify<direct_product<Ts...>>
418 using type = reduction<meta::reverse_t<reduce_t<count_and_combine_t<meta::stable_sort_t<direct_product<Ts...>, meta::type_comparator>>>>>;
422 template<class... Ts, class... Us>
423 struct simplify<direct_product<Ts...>, direct_product<Us...>>
425 using type = reduction<meta::reverse_t<reduce_t<count_and_combine_t<meta::merge_t<direct_product<Ts...>, direct_product<Us...>, meta::type_comparator>>>>>;
429 struct to_composite_space;
431 template<convex_space... Ts>
432 struct to_composite_space<reduction<direct_product<Ts...>>>
434 using type = composite_space<Ts...>;
437 template<physical_unit... Ts>
438 struct to_composite_space<reduction<direct_product<Ts...>>>
440 using type = composite_unit<Ts...>;
444 struct to_composite_space<reduction<direct_product<T>>>
450 using to_composite_space_t = to_composite_space<T>::type;
453namespace sequoia::maths
455 template<convex_space... Ts>
456 struct dual_of<physics::composite_space<Ts...>>
458 using type = physics::composite_space<dual_of_t<Ts>...>;
461 template<physics::physical_unit... Ts>
462 struct dual_of<physics::composite_unit<Ts...>>
464 using type = physics::composite_unit<dual_of_t<Ts>...>;
Abstractions pertaining to vector spaces, affine spaces and their generalizations.
Definition: PhysicalValuesDetails.hpp:44
Primary class template for defining duals.
Definition: Spaces.hpp:1041
Definition: PhysicalValues.hpp:769
Definition: PhysicalValues.hpp:142
Definition: PhysicalValues.hpp:129
Definition: PhysicalValuesDetails.hpp:23
Definition: PhysicalValues.hpp:53
Definition: PhysicalValues.hpp:136