16namespace sequoia::physics
25 requires maths::defines_identity_validator_v<T>
32 requires maths::defines_half_line_validator_v<T>
39 inline constexpr bool has_reciprocal_validator_v{
40 requires {
typename reciprocal_validator_t<T>; }
43 template<free_module M, physical_unit U>
46 using is_basis = std::true_type;
47 using free_module_type = M;
49 using isomorphism_type = units_type;
54 using is_unit = std::true_type;
61namespace sequoia::maths
63 template<physics::physical_unit T>
64 requires physics::has_reciprocal_validator_v<typename T::validator_type>
67 using is_unit = std::true_type;
68 using validator_type = physics::reciprocal_validator_t<typename T::validator_type>;
78 template<physics::physical_unit T>
79 requires (!physics::has_reciprocal_validator_v<typename T::validator_type>)
82 using is_unit = std::true_type;
83 using validator_type = void;
86 template<free_module M, physics::physical_unit U>
92 template<free_module M, physics::physical_unit U>
105namespace sequoia::physics
107 using namespace maths;
109 template<
class... Ts>
112 template<
class... Ts>
121 template<
class T,
class... Us>
124 using type = reduced_validator_t<T, reduced_validator_t<Us...>>;
130 using is_unit = std::true_type;
131 using validator_type = reduced_validator_t<
typename Ts::validator_type...>;
141 template<
class... Ts>
144 template<convex_space... Ts>
145 requires (free_module<Ts> || ...)
150 using commutative_ring_type = commutative_ring_type_of_t<direct_product_t>;
151 using is_free_module = std::true_type;
153 constexpr static std::size_t dimension{std::ranges::max({dimension_of<Ts>...})};
156 template<convex_space... Ts>
157 requires (!affine_space<Ts> && ...)
163 using is_convex_space = std::true_type;
166 using non_negative_orthant = std::bool_constant<(is_non_negative_orthant_v<Ts> && ...)>;
169 template<physical_unit... Us>
184 using type = impl::simplify_t<direct_product<T>,
direct_product<Us...>>;
193 template<convex_space... Ts>
199 template<convex_space... Ts, convex_space U>
205 template<convex_space T, convex_space... Us>
211 template<convex_space... Ts, convex_space... Us>
220 using type = std::identity;
224 requires (!std::is_same_v<T, std::identity>)
227 using type = std::identity;
236 template<convex_space ValueSpace, val
idator_for<ValueSpace> Val
idator>
237 inline constexpr bool has_consistent_validator{
238 !affine_space<ValueSpace> || defines_identity_validator_v<Validator>
241 template<convex_space ValueSpace>
242 inline constexpr bool has_consistent_space{
243 (!is_dual_v<ValueSpace>) || vector_space<ValueSpace> || (!affine_space<ValueSpace>)
247 convex_space ValueSpace,
249 basis_for<free_module_type_of_t<ValueSpace>> Basis,
251 validator_for<ValueSpace> Validator
253 requires has_consistent_space<ValueSpace>
254 && has_consistent_validator<ValueSpace, Validator>
255 class physical_value;
257 template<physical_unit Unit>
260 template<affine_space T>
263 template<convex_space T>
264 requires has_distinguished_origin_v<T>
267 template<convex_space ValueSpace, physical_unit Unit>
270 template<convex_space ValueSpace, physical_unit Unit>
271 requires (!has_distinguished_origin_v<ValueSpace>) && (!affine_space<ValueSpace>)
277 template<convex_space ValueSpace, physical_unit Unit>
280 template<convex_space ValueSpace, physical_unit Unit>
281 requires has_distinguished_origin_v<ValueSpace>
287 template<convex_space ValueSpace, physical_unit Unit>
288 requires (!has_distinguished_origin_v<ValueSpace> && affine_space<ValueSpace>)
289 struct to_origin_type<ValueSpace, Unit>
291 using type = implicit_affine_origin<ValueSpace>;
294 template<convex_space ValueSpace, physical_unit Unit, basis_for<free_module_type_of_t<ValueSpace>> Basis,
class Val
idator>
295 using to_coordinates_base_type
300 physical_value<free_module_type_of_t<ValueSpace>, Unit, Basis, distinguished_origin<free_module_type_of_t<ValueSpace>>, std::identity>>;
303 inline constexpr bool has_base_space_v{
304 requires {
typename T::base_space; }
307 template<convex_space T>
313 template<convex_space T>
314 using to_base_space_t = to_base_space<T>::type;
316 template<convex_space T>
317 requires has_base_space_v<T>
320 using type = T::base_space;
323 template<convex_space T>
329 template<convex_space T>
330 requires has_base_space_v<T>
336 template<convex_space... Ts>
339 using sorted_direct_product_t = meta::stable_sort_t<direct_product<to_base_space_t<Ts>...>, meta::type_comparator>;
340 using type = impl::to_composite_space_t<reduction<impl::reduce_t<impl::count_and_combine_t<sorted_direct_product_t>>>>;
343 template<convex_space T, convex_space U>
344 inline constexpr bool have_compatible_base_spaces_v{
345 has_base_space_v<T> && has_base_space_v<U> && (free_module_type_of_t<T>::dimension == free_module_type_of_t<U>::dimension) &&
requires {
346 typename std::common_type<typename T::base_space, typename U::base_space>::type;
350 template<convex_space T, convex_space U>
353 template<convex_space T, convex_space U>
356 template<convex_space T>
359 using type = free_module_type_of_t<T>;
362 template<convex_space T, convex_space U>
363 requires (!std::is_same_v<T, U>) && have_compatible_base_spaces_v<T, U>
366 using type = free_module_type_of_t<std::common_type_t<typename T::base_space, typename U::base_space>>;
369 template<basis Basis1, basis Basis2>
372 template<basis Basis1, basis Basis2>
375 template<free_module M1, physical_unit U1, free_module M2, physical_unit U2>
378 template<free_module M, physical_unit U>
382 template<
class T,
class U>
385 template<
class T,
class U>
388 template<physical_unit LHS, physical_unit RHS>
389 constexpr auto operator*(LHS, RHS)
noexcept
391 return impl::to_composite_space_t<reduction_t<direct_product<LHS, RHS>>>{};
394 template<physical_unit LHS>
395 constexpr auto operator*(LHS lhs, no_unit_t)
noexcept
400 template<physical_unit RHS>
401 requires (!std::same_as<RHS, no_unit_t>)
402 constexpr auto operator*(no_unit_t, RHS rhs)
noexcept
407 template<physical_unit LHS, physical_unit RHS>
408 constexpr auto operator/(LHS, RHS)
noexcept
410 return impl::to_composite_space_t<reduction_t<direct_product<LHS, dual_of_t<RHS>>>>{};
413 template<physical_unit LHS>
414 constexpr auto operator/(LHS lhs, no_unit_t)
noexcept
419 template<physical_unit RHS>
420 requires (!std::same_as<RHS, no_unit_t>)
421 constexpr auto operator/(no_unit_t, RHS)
noexcept
423 return dual_of_t<RHS>{};
427 convex_space LHSValueSpace, physical_unit LHSUnit, basis_for<free_module_type_of_t<LHSValueSpace>> LHSBasis,
class LHSValidator,
428 convex_space RHSValueSpace, physical_unit RHSUnit, basis_for<free_module_type_of_t<RHSValueSpace>> RHSBasis, class RHSValidator
430 requires consistent_bases_v<LHSBasis, RHSBasis>
434 using value_space_type = impl::to_composite_space_t<reduction_t<direct_product<LHSValueSpace, RHSValueSpace>>>;
435 using units_type = impl::to_composite_space_t<reduction_t<direct_product<LHSUnit, RHSUnit>>>;
442 reduced_validator_t<LHSValidator, RHSValidator>
446 template<
class From,
class To>
447 inline constexpr bool has_quantity_conversion_v{
448 has_coordinate_transformation_v<From, To> && std::constructible_from<coordinate_transformation<From, To>>
451 template<convex_space C, physical_unit FromUnit, physical_unit ToUnit>
457 template<convex_space C, physical_unit FromUnit, physical_unit ToUnit>
458 using conversion_space_t = conversion_space<C, FromUnit, ToUnit>::type;
460 template<convex_space ValueSpace, physical_unit Unit>
461 using default_validator_t = std::conditional_t<affine_space<ValueSpace>, std::identity,
typename Unit::validator_type>;
466 template<
class Rep,
class...>
469 template<
class Rep,
class... Args, std::size_t... Is>
470 requires (
sizeof...(Args) ==
sizeof...(Is) + 1)
471 &&
physical_unit<std::tuple_element_t<
sizeof...(Is), std::tuple<Args...>>>
472 && (std::convertible_to<std::tuple_element_t<Is, std::tuple<Args...>>, Rep> && ...)
478 template<
class Rep,
class... Args>
479 requires (
sizeof...(Args) > 1)
484 template<
class Rep,
class... Args>
488 convex_space ValueSpace,
490 basis_for<free_module_type_of_t<ValueSpace>> Basis = unit_defined_right_handed_basis<free_module_type_of_t<ValueSpace>, Unit>,
491 class Origin = to_origin_type_t<ValueSpace, Unit>,
492 validator_for<ValueSpace> Validator = default_validator_t<ValueSpace, Unit>
494 requires has_consistent_space<ValueSpace>
495 && has_consistent_validator<ValueSpace, Validator>
500 using space_type = ValueSpace;
501 using units_type = Unit;
502 using basis_type = Basis;
503 using origin_type = Origin;
504 using displacement_space_type = free_module_type_of_t<ValueSpace>;
505 using intrinsic_validator_type = Unit::validator_type;
506 using validator_type = Validator;
507 using ring_type = commutative_ring_type_of_t<ValueSpace>;
508 using value_type = ring_type;
509 using displacement_type = coordinates_type::displacement_coordinates_type;
511 constexpr static std::size_t dimension{displacement_space_type::dimension};
512 constexpr static std::size_t D{dimension};
514 constexpr static bool has_identity_validator{coordinates_type::has_identity_validator};
516 template<convex_space RHSValueSpace,
class RHSBasis>
517 constexpr static bool is_composable_with{
518 consistent_bases_v<basis_type, RHSBasis>
519 && (is_non_negative_orthant_v<space_type> || vector_space<space_type>)
520 && (is_non_negative_orthant_v<RHSValueSpace> || vector_space<RHSValueSpace>)
523 template<convex_space RHSValueSpace,
class RHSBasis>
524 constexpr static bool is_multipicable_with{
525 is_composable_with<RHSValueSpace, RHSBasis>
526 && ((D == 1) || (free_module_type_of_t<RHSValueSpace>::dimension == 1))
529 template<convex_space RHSValueSpace,
class RHSBasis>
530 constexpr static bool is_divisible_with{
531 weak_field<ring_type>
532 && weak_field<commutative_ring_type_of_t<RHSValueSpace>>
533 && is_composable_with<RHSValueSpace, RHSBasis>
534 && (free_module_type_of_t<RHSValueSpace>::dimension == 1)
537 using coordinates_type::coordinates_type;
539 using coordinates_type::operator+=;
541 template<convex_space OtherValueSpace, basis_for<free_module_type_of_t<OtherValueSpace>> OtherBasis,
class OtherOrigin>
542 requires (!std::same_as<space_type, OtherValueSpace>)
543 && has_distinguished_origin_v<space_type>
544 && (std::derived_from<OtherValueSpace, space_type>)
545 && consistent_bases_v<basis_type, OtherBasis>
548 return *
this = (*
this + other);
551 template<convex_space OtherValueSpace, basis_for<free_module_type_of_t<OtherValueSpace>> OtherBasis,
class OtherOrigin>
552 requires (!std::same_as<space_type, OtherValueSpace>)
553 && has_distinguished_origin_v<space_type>
554 && (std::derived_from<OtherValueSpace, space_type>)
555 && consistent_bases_v<basis_type, OtherBasis>
558 template<convex_space OtherValueSpace, basis_for<free_module_type_of_t<OtherValueSpace>> OtherBasis,
class OtherOrigin>
559 requires has_distinguished_origin_v<space_type>
560 && (!std::is_same_v<space_type, OtherValueSpace>)
561 && have_compatible_base_spaces_v<space_type, OtherValueSpace>
562 && consistent_bases_v<basis_type, OtherBasis>
566 using value_space_t = std::common_type_t<typename ValueSpace::base_space, typename OtherValueSpace::base_space>;
570 return [&] <std::size_t... Is>(std::index_sequence<Is...>) {
571 return physical_value_t{std::array{(lhs.values()[Is] + rhs.values()[Is])...}, units_type{}};
572 }(std::make_index_sequence<D>{});
575 template<
class OtherValueSpace, basis_for<free_module_type_of_t<OtherValueSpace>> OtherBasis,
class OtherOrigin>
576 requires (!std::same_as<OtherValueSpace, displacement_space_type>)
577 && (!std::same_as<space_type, OtherValueSpace> && have_compatible_base_spaces_v<space_type, OtherValueSpace>)
578 && consistent_bases_v<basis_type, OtherBasis>
581 noexcept(has_identity_validator)
583 using disp_space_t = to_displacement_space_t<ValueSpace, OtherValueSpace>;
585 using disp_t = to_coordinates_base_type<disp_space_t, Unit, basis_t, Validator>::displacement_coordinates_type;
586 return[&] <std::size_t... Is>(std::index_sequence<Is...>) {
587 return disp_t{std::array{(lhs.values()[Is] - rhs.values()[Is])...}, units_type{}};
588 }(std::make_index_sequence<D>{});
591 template<convex_space RHSValueSpace, physical_unit RHSUnit, basis_for<free_module_type_of_t<RHSValueSpace>> RHSBasis,
class RHSOrigin,
class RHSVal
idator>
592 requires is_multipicable_with<RHSValueSpace, RHSBasis>
597 using physical_value_t
598 = physical_value_product_t<
603 using derived_units_type = physical_value_t::units_type;
604 return physical_value_t{lhs.value() * rhs.value(), derived_units_type{}};
607 template<convex_space RHSValueSpace,
class RHSUnit, basis_for<free_module_type_of_t<RHSValueSpace>> RHSBasis,
class RHSOrigin,
class RHSVal
idator>
608 requires is_divisible_with<RHSValueSpace, RHSBasis>
613 using physical_value_t
614 = physical_value_product_t<
618 using derived_units_type = physical_value_t::units_type;
619 if constexpr(dimension == 1)
621 return physical_value_t{lhs.value() / rhs.value(), derived_units_type{}};
625 return[&] <std::size_t... Is>(std::index_sequence<Is...>) {
626 return physical_value_t{std::array{(lhs.values()[Is] / rhs.value())...}, derived_units_type{}};
627 }(std::make_index_sequence<D>{});
631 [[nodiscard]]
friend constexpr auto operator/(value_type value,
const physical_value& rhs)
632 requires ((D == 1) && (is_non_negative_orthant_v<space_type> || vector_space<ValueSpace>))
635 using derived_units_type = physical_value_t::units_type;
636 return physical_value_t{value / rhs.value(), derived_units_type{}};
640 template<
class LoweredValueSpace,
class OtherUnit, basis_for<free_module_type_of_t<LoweredValueSpace>> OtherBasis,
class OtherOrigin>
641 requires std::same_as<to_base_space_t<space_type>, to_base_space_t<LoweredValueSpace>> && consistent_bases_v<basis_type, OtherBasis>
645 using value_space_t = to_base_space_t<LoweredValueSpace>;
648 if constexpr(dimension == 1)
650 return physical_value_t{this->value(), OtherUnit{}};
654 return [
this] <std::size_t... Is>(std::index_sequence<Is...>) {
655 return physical_value_t{std::array{this->values()[Is]...}, OtherUnit{}};
656 }(std::make_index_sequence<D>{});
662 convex_space OtherSpace = conversion_space_t<ValueSpace, Unit, OtherUnit>,
664 class OtherOrigin = to_origin_type_t<OtherSpace, OtherUnit>,
665 validator_for<OtherSpace> OtherValidator = default_validator_t<OtherSpace, OtherUnit>
667 requires has_quantity_conversion_v<physical_value, physical_value<OtherSpace, OtherUnit, OtherBasis, OtherOrigin, OtherValidator>>
670 noexcept(has_noexcept_coordinate_transformation_v<physical_value, physical_value<OtherSpace, OtherUnit, OtherBasis, OtherOrigin, OtherValidator>>)
676 constexpr physical_value convert_to(Unit)
const noexcept {
return *
this; }
679 template<physical_unit Unit,
class Rep>
682 template<physical_unit Unit,
class Rep>
685 template<physical_unit Unit,
class Rep>
686 inline constexpr bool has_default_space_v{
688 typename default_space_t<Unit, Rep>;
692 template<physical_unit Unit,
class Rep>
693 requires has_default_space_v<Unit, Rep>
700 requires (has_default_space_v<Ts, Rep> && ...)
703 using type = impl::to_composite_space_t<reduction_t<direct_product<default_space_t<Ts, Rep>...>>>;
706 template<
class T, physical_unit U>
707 requires has_default_space_v<U, T>
710 namespace sets::classical
712 template<
class Arena>
715 using arena_type = Arena;
718 template<
class Arena>
721 using arena_type = Arena;
724 template<
class Arena>
727 using arena_type = Arena;
730 template<
class Arena>
733 using arena_type = Arena;
736 template<
class Arena>
739 using arena_type = Arena;
742 template<std::
size_t D,
class Arena>
745 using arena_type = Arena;
748 template<
class Arena>
751 using arena_type = Arena;
754 template<
class Arena>
757 using arena_type = Arena;
760 template<
class PhysicalValueSet>
763 using physical_value_set_type = PhysicalValueSet;
767 template<
class Space>
770 constexpr static std::size_t dimension{Space::dimension};
772 using commutative_ring_type = Space::representation_type;
773 using is_free_module = std::true_type;
774 using arena_type = Space::arena_type;
777 template<
class Space>
778 requires has_base_space_v<Space>
781 constexpr static std::size_t dimension{Space::dimension};
783 using commutative_ring_type = Space::representation_type;
784 using is_free_module = std::true_type;
786 using arena_type = Space::arena_type;
789 template<
class PhysicalValueSet, arithmetic Rep, std::
size_t D,
class Derived>
792 constexpr static std::size_t dimension{D};
793 using set_type = PhysicalValueSet;
794 using representation_type = Rep;
796 using is_convex_space = std::true_type;
797 using arena_type = PhysicalValueSet::arena_type;
800 template<
class PhysicalValueSet, arithmetic Rep, std::
size_t D,
class Derived>
803 constexpr static std::size_t dimension{D};
804 using set_type = PhysicalValueSet;
805 using representation_type = Rep;
807 using is_affine_space = std::true_type;
808 using arena_type = PhysicalValueSet::arena_type;
811 template<
class PhysicalValueSet, arithmetic Rep, std::
size_t D,
class Derived>
814 constexpr static std::size_t dimension{D};
815 using set_type = PhysicalValueSet;
816 using representation_type = Rep;
817 using field_type = Rep;
818 using is_vector_space = std::true_type;
821 template<std::
floating_po
int Rep,
class Arena>
825 using arena_type = Arena;
827 using distinguished_origin = std::true_type;
828 using non_negative_orthant = std::true_type;
831 template<std::
floating_po
int Rep,
class Arena>
835 using arena_type = Arena;
837 using distinguished_origin = std::true_type;
838 using non_negative_orthant = std::true_type;
841 template<convex_space C>
842 requires has_distinguished_origin_v<C>
847 using distinguished_origin = std::false_type;
848 using non_negative_orthant = std::false_type;
851 template<std::
floating_po
int Rep,
class Arena>
854 template<std::
floating_po
int Rep,
class Arena>
858 using arena_type = Arena;
862 template<std::
floating_po
int Rep,
class Arena>
865 using arena_type = Arena;
869 template<arithmetic Rep,
class Arena>
873 using arena_type = Arena;
875 using distinguished_origin = std::true_type;
876 using non_negative_orthant = std::true_type;
879 template<arithmetic Rep,
class Arena>
885 template<arithmetic Rep,
class Arena>
891 template<arithmetic Rep,
class Arena>
895 using arena_type = Arena;
896 using distinguished_origin = std::true_type;
897 using non_negative_orthant = std::true_type;
900 template<arithmetic Rep,
class Arena>
903 using arena_type = Arena;
906 template<arithmetic Rep, std::
size_t D,
class Arena>
909 using arena_type = Arena;
914 template<physical_unit U>
915 inline constexpr bool has_symbol_v{
917 { U::symbol } -> std::convertible_to<std::string_view>; }
920 template<
class Val
idator>
924 requires defines_identity_validator_v<T>
928 requires defines_half_line_validator_v<T>
931 template<
class Val
idator>
932 using scale_invariant_validator_t = scale_invariant_validator<Validator>::type;
934 template<
class Val
idator>
935 inline constexpr bool scale_invariant_validator_v{scale_invariant_validator<Validator>::value};
937 template<
class Val
idator>
943 template<
class Val
idator>
946 template<
class Val
idator>
952 template<
class... Ts>
953 using product_t =
product<Ts...>::type;
955 template<
class T,
class U,
class... Vs>
958 using tpye = product_t<product_t<T, U>, Vs...>;
967 template<auto Num, auto Den>
973 template<std::
intmax_t Num, std::
intmax_t Den>
979 template<auto Displacement>
980 requires arithmetic<std::remove_const_t<
decltype(Displacement)>>
983 using displacement_type = std::remove_const_t<
decltype(Displacement)>;
984 constexpr static auto displacement{Displacement};
987 template<auto Displacement>
1002 template<physical_unit U,
class Ratio, auto Displacement>
1003 requires scale_invariant_validator_v<typename U::validator_type> && (translation_invariant_validator_v<typename U::validator_type> || !Displacement)
1006 using type = U::validator_type;
1009 template<physical_unit U,
class Ratio, auto Displacement>
1010 requires scale_invariant_validator_v<typename U::validator_type> && (Displacement != 0)
1013 using value_type = std::remove_cv_t<
decltype(Displacement)>;
1017 template<physical_unit U,
class Ratio, auto Displacement>
1018 requires (!scale_invariant_validator_v<typename U::validator_type>) && is_interval_validator_v<typename U::validator_type>
1019 struct synthesised_validator<coordinate_transform<U, dilatation<Ratio>, translation<Displacement>>>
1021 using underlying_validator_type = U::validator_type;
1022 using value_type = std::remove_cv_t<
decltype(underlying_validator_type::lower)>;
1025 constexpr static value_type transform(value_type val) {
1026 return (val * Ratio::num / Ratio::den) + Displacement;
1029 using type = interval_validator<value_type, transform(underlying_validator_type::lower), transform(underlying_validator_type::upper)>;
1032 template<physical_unit U,
class Ratio, auto Displacement>
1035 using is_unit = std::true_type;
1037 using validator_type = synthesised_validator_t<transform_type>;
1038 using with_respect_to_type = U;
1043 template<physical_unit U,
class Ratio, auto Displacement>
1046 using inverse_dil_type = inverse_t<dilatation<Ratio>>;
1047 using inverse_ratio_type = inverse_dil_type::ratio_type;
1052 physical_unit LHSUnit,
class LHSRatio,
auto LHSDisplacement,
1072 template<physical_unit U,
class Ratio, auto Displacement>
1075 template<physical_unit U>
1076 inline constexpr bool has_coordinate_transform_v{
1078 typename U::transform_type;
1079 requires is_coordinate_transform_v<typename U::transform_type>;
1083 template<physical_unit U>
1084 inline constexpr bool derives_from_another_unit_v{
1086 typename U::with_respect_to_type;
1087 requires physical_unit<typename U::with_respect_to_type>;
1091 template<physical_unit U>
1095 using units_type = U;
1098 template<physical_unit U>
1101 template<physical_unit U>
1102 using root_transform_unit_t = root_transform<U>::units_type;
1104 template<physical_unit U>
1105 requires derives_from_another_unit_v<U>
1106 && (!derives_from_another_unit_v<typename U::with_respect_to_type>)
1109 using transform_type = U::transform_type;
1112 template<physical_unit U>
1113 requires derives_from_another_unit_v<U>
1114 && derives_from_another_unit_v<typename U::with_respect_to_type>
1117 using wrt_type =
typename U::with_respect_to_type;
1119 using transform_type = product_t<typename U::transform_type, nested_transform_type>;
1122 template<physical_unit... Us>
1123 requires (scale_invariant_validator_v<typename Us::validator_type> && ...)
1126 using units_type =
decltype((root_transform_unit_t<Us>{} * ...));
1127 using transform_type = product_t<root_transform_t<Us>...>;
1139 template<physical_unit U,
class Ratio, auto Displacement>
1141 : std::bool_constant<Ratio::num == Ratio::den>
1153 template<physical_unit U,
class Ratio, auto Displacement>
1155 : std::bool_constant<Displacement == 0>
1158 template<convex_space C, physical_unit FromUnit, physical_unit ToUnit>
1159 requires (!has_distinguished_origin_v<C>)
1166 template<convex_space C, physical_unit FromUnit, physical_unit ToUnit>
1167 requires has_distinguished_origin_v<C>
1168 && (has_identity_translation_v<root_transform_t<FromUnit>> && !has_identity_translation_v<root_transform_t<ToUnit>>)
1174 template<convex_space C, physical_unit FromUnit, physical_unit ToUnit>
1175 requires has_distinguished_origin_v<C> && has_identity_translation_v<root_transform_t<ToUnit>>
1181 template<physical_unit Unit>
1184 using validator_type = Unit::validator_type;
1188 template<physical_unit Unit>
1191 using validator_type = Unit::validator_type;
1195 template<physical_unit Unit>
1198 using validator_type = Unit::validator_type;
1202 template<physical_unit Unit>
1205 using validator_type = Unit::validator_type;
1215 inline namespace units
1219 using is_unit = std::true_type;
1220 using validator_type = std::identity;
1221 constexpr static std::string_view symbol{
"A"};
1226 using is_unit = std::true_type;
1228 constexpr static std::string_view symbol{
"kg"};
1233 using is_unit = std::true_type;
1235 constexpr static std::string_view symbol{
"m"};
1240 using is_unit = std::true_type;
1242 constexpr static std::string_view symbol{
"s"};
1247 using is_unit = std::true_type;
1249 constexpr static std::string_view symbol{
"K"};
1254 using is_unit = std::true_type;
1255 using validator_type = std::identity;
1256 constexpr static std::string_view symbol{
"C"};
1261 using is_unit = std::true_type;
1262 using validator_type = std::identity;
1263 constexpr static std::string_view symbol{
"rad"};
1268 constexpr static std::string_view symbol{
"degC"};
1271 inline constexpr ampere_t ampere{};
1272 inline constexpr kilogram_t kilogram{};
1273 inline constexpr metre_t metre{};
1274 inline constexpr second_t second{};
1275 inline constexpr kelvin_t kelvin{};
1276 inline constexpr coulomb_t coulomb{};
1277 inline constexpr radian_t radian{};
1279 inline constexpr celsius_t celsius{};
1281 using milligram_t = micro<si::units::kilogram_t>;
1282 using gram_t = milli<si::units::kilogram_t>;
1283 using tonne_t = kilo<si::units::kilogram_t>;
1284 using kilotonne_t = mega<si::units::kilogram_t>;
1286 inline constexpr milligram_t milligram{};
1287 inline constexpr gram_t gram{};
1288 inline constexpr tonne_t tonne{};
1289 inline constexpr kilotonne_t kilotonne{};
1292 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1293 using mass = physical_value<mass_space<T, Arena>, units::kilogram_t>;
1295 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1296 using length = physical_value<length_space<T, Arena>, units::metre_t>;
1298 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1299 using time_interval = physical_value<time_interval_space<T, Arena>, units::second_t>;
1301 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1302 using temperature = physical_value<absolute_temperature_space<T, Arena>, units::kelvin_t>;
1304 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1305 using temperature_celsius = physical_value<temperature_space<T, Arena>, units::celsius_t>;
1307 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1308 using electrical_current = physical_value<electrical_current_space<T, Arena>, units::ampere_t>;
1310 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1311 using angle = physical_value<angular_space<T, Arena>, units::radian_t>;
1313 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1314 using width = physical_value<width_space<T, Arena>, units::metre_t>;
1316 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1317 using height = physical_value<height_space<T, Arena>, units::metre_t>;
1320 std::floating_point T,
1321 class Arena=implicit_common_arena,
1322 class Origin=implicit_affine_origin<time_space<T, Arena>>
1326 time_space<T, Arena>,
1328 unit_defined_right_handed_basis<free_module_type_of_t<time_space<T, Arena>>, units::second_t>,
1334 std::floating_point T,
1336 class Arena = implicit_common_arena,
1337 basis_for<free_module_type_of_t<position_space<T, D, Arena>>> Basis = unit_defined_right_handed_basis<free_module_type_of_t<position_space<T, D, Arena>>, units::metre_t>,
1338 class Origin = implicit_affine_origin<position_space<T, D, Arena>>
1340 using position = physical_value<position_space<T, D, Arena>, units::metre_t, Basis, Origin, std::identity>;
1344 inline namespace non_si
1346 inline namespace units
1350 using is_unit = std::true_type;
1351 using validator_type = std::identity;
1352 constexpr static std::string_view symbol{
"deg"};
1357 using is_unit = std::true_type;
1358 using validator_type = std::identity;
1359 constexpr static std::string_view symbol{
"gon"};
1362 inline constexpr degree_t degree{};
1363 inline constexpr gradian_t gradian{};
1367 using is_unit = std::true_type;
1368 constexpr static std::string_view symbol{
"degF"};
1375 using is_unit = std::true_type;
1376 constexpr static std::string_view symbol{
"ft"};
1379 inline constexpr foot_t foot{};
1382 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1383 using temperature_farenheight = physical_value<temperature_space<T, Arena>, units::farenheight_t>;
1386 template<convex_space C, physical_unit FromUnit, physical_unit ToUnit>
1392 template<physical_unit Unit,
class Rep,
class Ratio, auto Trans>
1393 requires has_default_space_v<Unit, Rep> && (Trans == 0)
1396 template<physical_unit Unit,
class Rep>
1397 requires has_coordinate_transform_v<Unit>
1400 template<std::
floating_po
int T>
1406 template<std::
floating_po
int T>
1412 template<std::
floating_po
int T>
1418 template<std::
floating_po
int T>
1424 template<std::
floating_po
int T>
1430 template<std::
floating_po
int T>
1436 template<vector_space ValueSpace, physical_unit Unit,
class Basis,
class Origin, val
idator_for<ValueSpace> Val
idator>
1437 requires (dimension_of<ValueSpace> == 1)
1441 return {std::abs(q.value()), Unit{}};
1444 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1446 constexpr T sin(physical_value<angular_space<T, Arena>, si::units::radian_t> theta)
1448 return std::sin(theta.value());
1451 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1453 constexpr T cos(physical_value<angular_space<T, Arena>, si::units::radian_t> theta)
1455 return std::cos(theta.value());
1458 template<std::
floating_po
int T,
class Arena=implicit_common_arena>
1460 constexpr T tan(physical_value<angular_space<T, Arena>, si::units::radian_t> theta)
1462 return std::tan(theta.value());
1465 template<
class Arena=implicit_common_arena, std::
floating_po
int T>
1467 constexpr physical_value<angular_space<T, Arena>, si::units::radian_t> asin(T x)
1469 return {std::asin(x), si::units::radian};
1472 template<
class Arena=implicit_common_arena, std::
floating_po
int T>
1474 constexpr physical_value<angular_space<T, Arena>, si::units::radian_t> acos(T x)
1476 return {std::acos(x), si::units::radian};
1479 template<
class Arena=implicit_common_arena, std::
floating_po
int T>
1481 constexpr physical_value<angular_space<T, Arena>, si::units::radian_t> atan(T x)
1483 return {std::atan(x), si::units::radian};
1486 template<physical_unit Unit,
class Rep,
class Val
idator=
typename Unit::val
idator_type>
1487 requires has_default_space_v<Unit, Rep>
1488 using quantity = physical_value<default_space_t<Unit, Rep>, Unit, unit_defined_right_handed_basis<free_module_type_of_t<default_space_t<Unit, Rep>>, Unit>, to_origin_type_t<default_space_t<Unit, Rep>, Unit>, Validator>;
1491 convex_space ValueSpace,
1493 validator_for<ValueSpace> Validator=
typename Unit::validator_type
1495 requires has_consistent_validator<ValueSpace, Validator>
1496 using dimensionless_quantity = physical_value<ValueSpace, Unit, unit_defined_right_handed_basis<free_module_type_of_t<ValueSpace>, Unit>, to_origin_type_t<ValueSpace, Unit>, Validator>;
1498 template<std::
floating_po
int Rep,
class Arena=implicit_common_arena>
1499 using euclidean_1d_vector_quantity = dimensionless_quantity<euclidean_vector_space<Rep, 1, Arena>, no_unit_t, std::identity>;
1501 template<std::
floating_po
int Rep,
class Arena=implicit_common_arena>
1502 using euclidean_half_line_quantity = dimensionless_quantity<euclidean_half_space<Rep, Arena>, no_unit_t>;
1505namespace sequoia::maths
1507 using namespace physics;
1510 convex_space ValueSpaceFrom,
1511 physical_unit UnitFrom,
1512 basis_for<free_module_type_of_t<ValueSpaceFrom>> BasisFrom,
1514 validator_for<ValueSpaceFrom> ValidatorFrom,
1515 convex_space ValueSpaceTo,
1516 basis_for<free_module_type_of_t<ValueSpaceTo>> BasisTo,
1517 physical_unit UnitTo,
1519 validator_for<ValueSpaceTo> ValidatorTo
1521 requires std::same_as<root_transform_unit_t<UnitFrom>, root_transform_unit_t<UnitTo>>
1523 physical_value<ValueSpaceFrom, UnitFrom, BasisFrom, OriginFrom, ValidatorFrom>,
1524 physical_value<ValueSpaceTo, UnitTo, BasisTo, OriginTo, ValidatorTo>
1527 using value_type = commutative_ring_type_of_t<ValueSpaceFrom>;
1528 using from_units_type = UnitFrom;
1530 using to_units_type = UnitTo;
1532 using transform_type = product_t<root_transform_t<UnitTo>, inverse_t<root_transform_t<UnitFrom>>>;
1534 constexpr static auto to_displacement()
noexcept {
1536 return value_type{};
1538 return transform_type::translation_type::displacement;
1545 utilities::to_array(
1547 [](value_type v) -> value_type {
1548 using ratio_type = transform_type::dilatation_type::ratio_type;
1550 return static_cast<value_type>((v * ratio_type::num / ratio_type::den) + to_displacement());
1566struct std::formatter<sequoia::physics::physical_value<ValueSpace, Unit, Basis, Origin, Validator>>
1569 constexpr static auto dimension{sequoia::maths::dimension_of<ValueSpace> };
1571 constexpr auto parse(
auto& ctx)
1577 requires (dimension == 1)
1579 if constexpr(sequoia::physics::has_symbol_v<Unit>)
1580 return std::format_to(ctx.out(),
"{} {}", v.value(), Unit::symbol);
1582 return std::format_to(ctx.out(),
"{}", v.value());
Definition: Spaces.hpp:1321
Definition: PhysicalValues.hpp:497
\brieft A concept for arithmetic types
Definition: Concepts.hpp:81
A concept to determine if a basis is appropriate for a particular free module.
Definition: Spaces.hpp:692
concept for convex spaces
Definition: Spaces.hpp:518
concept for a free module, implicitly understood to be over a commutative ring.
Definition: Spaces.hpp:477
concept to check if a validator is compatible with a convex space.
Definition: Spaces.hpp:749
Definition: PhysicalValuesDetails.hpp:44
Definition: Spaces.hpp:1955
Definition: Spaces.hpp:907
Definition: Spaces.hpp:896
Specialization for units, such as degrees Celsius, for which the corresponding quantity cannot be inv...
Definition: PhysicalValues.hpp:66
Helper to generate the dual of a space, taking into account that the dual of the dual may be related ...
Definition: Spaces.hpp:1109
Primary class template for defining duals.
Definition: Spaces.hpp:1041
A validator for the half line.
Definition: Spaces.hpp:776
Definition: Spaces.hpp:665
A generic interval validator for floating-point types.
Definition: Spaces.hpp:800
Definition: PhysicalValues.hpp:834
Definition: PhysicalValues.hpp:864
Definition: PhysicalValues.hpp:769
Definition: PhysicalValues.hpp:142
Definition: PhysicalValues.hpp:129
Definition: PhysicalValues.hpp:370
Definition: PhysicalValues.hpp:453
Definition: PhysicalValues.hpp:680
Definition: PhysicalValues.hpp:265
Definition: PhysicalValues.hpp:857
Definition: PhysicalValues.hpp:1131
Definition: PhysicalValues.hpp:1145
Definition: PhysicalValues.hpp:888
Definition: PhysicalValues.hpp:887
Definition: PhysicalValues.hpp:467
Definition: PhysicalValues.hpp:261
Definition: PhysicalValues.hpp:912
Definition: PhysicalValues.hpp:962
Definition: PhysicalValues.hpp:1197
Definition: PhysicalValues.hpp:872
Definition: PhysicalValues.hpp:824
Definition: PhysicalValues.hpp:1204
Definition: PhysicalValues.hpp:1183
Definition: PhysicalValues.hpp:1190
Definition: PhysicalValues.hpp:53
Definition: PhysicalValues.hpp:1349
Definition: PhysicalValues.hpp:1366
Definition: PhysicalValues.hpp:1356
Definition: PhysicalValues.hpp:802
Definition: PhysicalValues.hpp:791
Definition: PhysicalValues.hpp:383
Definition: PhysicalValues.hpp:813
Definition: PhysicalValues.hpp:908
Definition: PhysicalValues.hpp:950
Definition: PhysicalValues.hpp:19
Definition: PhysicalValues.hpp:110
Definition: PhysicalValues.hpp:136
Definition: PhysicalValues.hpp:844
Definition: PhysicalValues.hpp:921
Definition: PhysicalValues.hpp:756
Definition: PhysicalValues.hpp:762
Definition: PhysicalValues.hpp:726
Definition: PhysicalValues.hpp:750
Definition: PhysicalValues.hpp:714
Definition: PhysicalValues.hpp:744
Definition: PhysicalValues.hpp:720
Definition: PhysicalValues.hpp:738
Definition: PhysicalValues.hpp:732
Definition: PhysicalValues.hpp:1218
Definition: PhysicalValues.hpp:1267
Definition: PhysicalValues.hpp:1253
Definition: PhysicalValues.hpp:1246
Definition: PhysicalValues.hpp:1225
Definition: PhysicalValues.hpp:1232
Definition: PhysicalValues.hpp:1260
Definition: PhysicalValues.hpp:1239
Definition: PhysicalValues.hpp:994
Definition: PhysicalValues.hpp:894
Definition: PhysicalValues.hpp:902
Definition: PhysicalValues.hpp:309
Definition: PhysicalValues.hpp:351
Definition: PhysicalValues.hpp:268
Definition: PhysicalValues.hpp:938
Definition: PhysicalValues.hpp:982
Definition: PhysicalValues.hpp:258
Definition: PhysicalValues.hpp:45
Definition: PhysicalValues.hpp:882
Definition: PhysicalValues.hpp:881
Detects value_type.
Definition: Iterator.hpp:111