akreon-convex
Typed convex modeling, conic canonicalization, and primal-dual optimization in C++26.
Loading...
Searching...
No Matches
ellipsoid.hpp
Go to the documentation of this file.
1/*
2 * Copyright © 2025-2026 Akreon LLC
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#pragma once
7
8#include "convex_set.hpp"
9#include "akreon/linalg/operator/symmetric_matrix.hpp"
10
11namespace convex {
12
14template <linalg::RnSpace Space>
16
18template <linalg::RnSpace Space>
20
22template <linalg::RnSpace Space>
25
31template <typename Meta, typename Child>
32struct Ellipsoid : ConvexSet<Meta, Ellipsoid<Meta, Child>, Child> {
37
39 using ConvexBase::N;
40
42 using Mat = linalg::Matrix<T, N, N>;
43
51 constexpr explicit Ellipsoid(const PointT& c_in, const Mat& P_in,
52 const Child& child_in)
53 : ConvexBase(child_in), c(c_in), P(P_in) {}
54
64 constexpr bool contains_impl(const PointT& x, T /* tol */) const {
65 const auto delta = x - c;
66 const auto delta_T = linalg::transpose(as_col_vector(delta));
67 const auto [P_inv, event] = linalg::MatrixInverse<decltype(P)>()(P);
68 static_cast<void>(event);
69 const auto res = (delta_T * (P_inv * delta));
70 static_assert(linalg::vector_dim_v<decltype(res)> == 1);
71 return res(0) <= T(1);
72 }
73
79 constexpr bool is_well_formed() const {
80 linalg::SymmetricMatrix S(P);
81 return S.type == linalg::SymmetricOperatorType::PD;
82 }
83
101 template <linalg::SquareMatrix Mat>
102 requires(linalg::mat_cols_v<Mat> == N &&
103 std::same_as<T, linalg::matrix_scalar_t<Mat>>)
104 constexpr auto transform_impl(const affine::AffineMap<Mat>& map) const {
105 const auto [U_inv, event] = linalg::MatrixInverse<Mat>()(map.linear_part());
106 static_cast<void>(event);
107 return Ellipsoid<Meta, Child>(map.linear_part() * c + map.translation(),
108 transpose(U_inv) * P * U_inv,
109 std::get<0>(this->children));
110 }
111
119 template <typename Other>
120 constexpr bool is_equal_impl(const Other& other) const {
121 return other.self().c == c && other.self().P == P;
122 }
123
143 template <AtomType Type, conic::BuilderLike Builder>
144 constexpr auto canonicalize_set(const Builder& builder) const {
145 const auto child_builder =
146 std::get<0>(this->children)
147 .template canonicalize<AtomType::SET>(builder);
148 const auto child_coord = child_builder.coord_map;
149
150 static constexpr std::size_t ChildCodom =
151 linalg::mat_cols_v<decltype(child_coord.linear_part())>;
152 static_assert(ChildCodom == N,
153 "Convex set domain does not equal the child coordinate "
154 "linear map's codomain in size");
155
156 linalg::Matrix<T, N + 1, N> F;
157 linalg::Vector<T, N + 1> g;
158 const auto eig_decomp = linalg::EigenDecomposition(P);
159 const auto& D = eig_decomp.lambda;
160 linalg::Matrix<T, N, N> D_sqrt;
161 for (std::size_t i = 0; i < N; ++i)
162 D_sqrt(i, i) = linalg::constexpr_sqrt_safe(D(i).real());
163
164 linalg::Matrix<T, N, N> VT;
165 const auto& V = eig_decomp.V;
166 for (std::size_t i = 0; i < N; ++i)
167 for (std::size_t j = 0; j < N; ++j) VT(j, i) = V(i, j).real();
168
169 const auto w = D_sqrt * VT;
170 F = linalg::set_block<0, N, 0, N>(F, w);
171 const auto wc = T(-1) * w * c;
172 for (std::size_t i = 0; i < N; ++i) g(i) = wc(i);
173 g(N) = T(1);
174 const auto map = affine::AffineMap<decltype(F)>(F, g);
176 const auto cones = std::make_tuple(soc);
177 const auto emission =
178 conic::LocalEmission(map, cones, child_builder.eq_map);
179
180 return child_builder.template realize<Type>(emission);
181 }
182
184 PointT c; //< n-dim vector of type T representing center of ellipsoid
185 Mat P; //< square matrix representing directions for ellipsoid (valid in
186 // S^n_+)
187};
188
189template <typename Point, typename Mat, typename Child>
190Ellipsoid(const Point&, const Mat&, const Child&)
193
194} // namespace convex
constexpr std::size_t dom_size_v
linalg::remove_cvref_t< T > atom_decay_t
normalize atom-facing types to a stable internal form.
Atom-local canonical emission bundle.
forward decl for soc
Definition soc.hpp:128
ChildrenT children
Tuple of normalized child atoms.
Definition atom.hpp:240
dom_point_t< Domain > PointT
Point type accepted by the atom domain.
Definition atom.hpp:32
dom_type_t< Domain > T
Scalar field for the atom domain.
Definition atom.hpp:30
static constexpr std::size_t N
Domain dimension.
Definition atom.hpp:35
Atom metadata bundling domain, codomain, and curvature.
Domain wrapper with a static sign label.
forward declaration of convex set
forward declaration of ellipsoid set
Definition ellipsoid.hpp:32
linalg::Matrix< T, N, N > Mat
common mat type for P
Definition ellipsoid.hpp:42
PointT c
member variables in the ellipsoid
constexpr bool is_well_formed() const
is_well_formed implementation checks to see if set is valid
Definition ellipsoid.hpp:79
constexpr auto canonicalize_set(const Builder &builder) const
canonicalize impl
constexpr Ellipsoid(const PointT &c_in, const Mat &P_in, const Child &child_in)
CTOR for ellipsoidal set.
Definition ellipsoid.hpp:51
constexpr auto transform_impl(const affine::AffineMap< Mat > &map) const
transform set from an affine map
constexpr bool contains_impl(const PointT &x, T) const
contains function to see if x is in the ellipsoid (x - c)^T P^{-1} (x - c) <= 1
Definition ellipsoid.hpp:64
constexpr bool is_equal_impl(const Other &other) const
equality comparison