akreon-convex
Typed convex modeling, conic canonicalization, and primal-dual optimization in C++26.
Loading...
Searching...
No Matches
lmi.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
8
9#include "convex_set.hpp"
10
11namespace convex {
12
14template <linalg::RnSpace Space>
16
18template <linalg::RnSpace Space>
20
22template <linalg::RnSpace Space>
23using LMIMeta =
25
32template <typename Meta, typename Child, linalg::SquareMatrix MatIn>
33struct LMI : ConvexSet<Meta, LMI<Meta, Child, MatIn>, Child> {
38
40 using ConvexBase::N;
41
43 using Mat = linalg::remove_cvref_t<MatIn>;
44 static constexpr std::size_t MatDim = linalg::mat_rows_v<Mat>;
45 static_assert(linalg::mat_cols_v<Mat> == MatDim,
46 "LMI expects square coefficient matrices");
47
54 constexpr explicit LMI(const linalg::Vector<Mat, N>& A_in, const Mat& B_in,
55 const Child& child_in)
56 : ConvexBase(child_in), A(A_in), B(B_in) {}
57
69 constexpr bool contains_impl(const PointT& x, T /* tol */) const {
70 auto res = B;
71 for (std::size_t i = 0; i < N; ++i) res = res + (x(i) * A(i));
72 linalg::LDL ldl(res);
73 return ldl.is_psd();
74 }
75
84 constexpr bool is_well_formed() const { return true; }
85
93 template <typename Other>
94 constexpr bool is_equal_impl(const Other& other) const {
95 if (!linalg::all_equal(B, other.B)) return false;
96 for (std::size_t i = 0; i < N; ++i)
97 if (!linalg::all_equal(A(i), other.A(i))) return false;
98 return true;
99 }
100
108 template <linalg::MatrixContainer Mat>
109 constexpr auto transform_impl(const affine::AffineMap<Mat>& /* map */) const {
110 AK_ASSERT(false && "LMI does not support transformations");
111 }
112
123 template <AtomType Type, conic::BuilderLike Builder>
124 constexpr auto canonicalize(const Builder& builder) const {
125 const auto child_builder =
126 std::get<0>(this->children)
127 .template canonicalize<AtomType::SET>(builder);
128 const auto child_coord = child_builder.coord_map;
129
130 static constexpr std::size_t ChildCodom =
131 linalg::mat_cols_v<decltype(child_coord.linear_part())>;
132 static_assert(ChildCodom == N,
133 "Convex set domain does not equal the child coordinate "
134 "linear map's codomain in size");
135
136 static constexpr std::size_t K = MatDim * (MatDim + 1) / 2;
137 linalg::Matrix<T, K, N> F_local{};
138 linalg::Vector<T, K> g_local{};
139
140 auto update_F = [&F_local](const auto& i, const auto& M) {
141 const auto m_svec = linalg::get_svec(M);
142 for (std::size_t row_idx = 0; row_idx < K; ++row_idx)
144 };
145
146 auto update_g = [&g_local](const auto& M) {
147 g_local = linalg::get_svec(M);
148 };
149
150 for (std::size_t i = 0; i < N; ++i) update_F(i, A(i));
151 update_g(B);
152
153 const auto F = F_local * child_coord.linear_part();
154 const auto g = F_local * child_coord.translation() + g_local;
155
156 const auto map = affine::AffineMap<decltype(F)>(F, g);
157 const auto psd_cone =
159 const auto cones = std::make_tuple(psd_cone);
160 const auto emission =
161 conic::LocalEmission(map, cones, child_builder.eq_map);
162
163 return child_builder.template realize<Type>(emission);
164 }
165
167 linalg::Vector<Mat, N> A;
169};
170
173template <typename Mat, std::size_t N, typename Child>
174LMI(const linalg::Vector<Mat, N>&, const Mat&, const Child&)
177
178} // 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 psd
Definition psd_cone.hpp:49
static constexpr std::size_t M
Codomain dimension.
Definition atom.hpp:37
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 LMI type
Definition lmi.hpp:33
constexpr bool is_equal_impl(const Other &other) const
equality comparison
Definition lmi.hpp:94
constexpr auto transform_impl(const affine::AffineMap< Mat > &) const
transform impl
Definition lmi.hpp:109
constexpr auto canonicalize(const Builder &builder) const
canonicalize impl
Definition lmi.hpp:124
static constexpr std::size_t MatDim
Definition lmi.hpp:44
Mat B
B offset.
Definition lmi.hpp:168
constexpr bool is_well_formed() const
is_well_formed to check if the set is valid
Definition lmi.hpp:84
constexpr LMI(const linalg::Vector< Mat, N > &A_in, const Mat &B_in, const Child &child_in)
CTOR for LMI A & B split out.
Definition lmi.hpp:54
linalg::Vector< Mat, N > A
member vars for LMI
Definition lmi.hpp:167
constexpr bool contains_impl(const PointT &x, T) const
contains function to see if x is in the LMI defined as
Definition lmi.hpp:69
linalg::remove_cvref_t< MatIn > Mat
lifted matrix for P
Definition lmi.hpp:43