8#include "akreon/linalg/affine/affine_map.hpp"
22template <
typename SumCodomain,
typename Child>
27 "Sum child codomain must match the sum codomain space");
38template <affine::AffineMapLike PrevMap, affine::AffineMapLike NextMap>
40 using PrevMatT = affine::affine_mat_t<PrevMap>;
41 using NextMatT = affine::affine_mat_t<NextMap>;
42 using T = linalg::matrix_scalar_t<PrevMatT>;
44 static constexpr std::size_t
PrevDom = linalg::mat_cols_v<PrevMatT>;
45 static constexpr std::size_t
PrevCodom = linalg::mat_rows_v<PrevMatT>;
47 static constexpr std::size_t
NextDom = linalg::mat_cols_v<NextMatT>;
48 static constexpr std::size_t
NextCodom = linalg::mat_rows_v<NextMatT>;
53 return affine::AffineMap<linalg::remove_cvref_t<NextMatT>>(
54 next.linear_part(),
next.translation());
56 static constexpr std::size_t
FullDom =
58 linalg::Matrix<T, PrevCodom, FullDom>
F{};
66 linalg::Vector<T, PrevCodom>
g{};
70 return affine::AffineMap<decltype(F)>(
F,
g);
90template <std::size_t idx = 0,
typename Children,
typename Builder,
typename Fn,
91 affine::AffineMapLike Map>
94 constexpr std::size_t N =
95 std::tuple_size_v<std::remove_reference_t<Children>>;
96 if constexpr (idx == N)
97 return std::tuple(
selector, std::forward<Builder>(builder));
99 auto&&
child = std::get<idx>(std::forward<Children>(children));
101 std::forward<Fn>(
fn)(
child, std::forward<Builder>(builder));
103 if constexpr (idx == 0)
return new_builder.coord_map;
115template <
typename Meta,
typename...
Cs>
116struct Sum :
Atom<Meta, Sum<Meta, Cs...>, Cs...> {
128 "Size of domain is not equal to children");
129 static_assert(
sizeof...(Cs) > 1,
"Number of children not greater than 1");
131 using MatT = linalg::Matrix<T, 1, 1>;
149 constexpr explicit Sum(
const affine::AffineMap<MatT>&
map_in,
150 const std::tuple<Cs...>&
cs)
163 constexpr auto mul()
const {
164 affine::AffineMap<MatT>
new_map(Scalar *
map.linear_part(),
176 constexpr auto add(
T beta)
const {
177 affine::AffineMap<MatT>
new_map(
178 map.linear_part(), linalg::Vector<T, 1>{beta} +
map.translation());
192 template <AtomType Type, conic::BuilderLike Builder>
194 static_assert(Type !=
AtomType::SET,
"Minkowski sum is not yet supported");
201 const auto selector = std::get<0>(res);
202 const auto F =
map.linear_part()(0, 0) *
selector.linear_part();
204 map.linear_part()(0, 0) *
selector.translation() +
map.translation();
206 affine::AffineMap<
decltype(
selector.linear_part())>(
F,
g);
219 affine::AffineMap<MatT>
226template <
typename C0,
typename...
Cs>
typename builder_traits< linalg::remove_cvref_t< Builder > >::Dom builder_dom_t
builder domain
typename dom_traits< linalg::remove_cvref_t< Dom > >::Space dom_space_t
constexpr void validate_sum_child_codomain()
Validate that a sum child has the same codomain as the parent sum.
constexpr std::size_t dom_size_v
linalg::remove_cvref_t< T > atom_decay_t
normalize atom-facing types to a stable internal form.
constexpr auto update_selector(const PrevMap &prev, const NextMap &next)
Accumulate the affine selector for a sum atom.
typename meta_traits< linalg::remove_cvref_t< Meta > >::Codomain meta_codom_t
typename atom_traits< atom_decay_t< Atom > >::ConvexMeta atom_meta_t
Extract metadata type from atom.
constexpr auto tuple_fold_sum(Children &&children, Builder &&builder, Fn &&fn, Map &&selector)
Canonicalize and fold all sum children.
CRTP base for convex atoms.
meta_codom_t< Meta > Codomain
Atom output codomain.
ChildrenT children
Tuple of normalized child atoms.
dom_point_t< Domain > PointT
Point type accepted by the atom domain.
meta_dom_t< Meta > Domain
Atom input domain.
dom_type_t< Domain > T
Scalar field for the atom domain.
forward declaration - sum op
constexpr auto mul() const
Scale this sum by a compile-time scalar.
constexpr Sum(const Cs &... cs)
Construct a sum atom from child atoms.
constexpr auto canonicalize_impl(const Builder &builder) const
Canonicalize this sum into a cone builder.
constexpr auto add(T beta) const
Add a scalar offset to this sum.
affine::AffineMap< MatT > map
Scalar affine transform applied after summing children.
linalg::Matrix< T, 1, 1 > MatT
Scalar affine map matrix type.
constexpr Sum(const affine::AffineMap< MatT > &map_in, const std::tuple< Cs... > &cs)
Construct a transformed sum atom from a scalar affine map.