akreon-convex
Typed convex modeling, conic canonicalization, and primal-dual optimization in C++26.
Loading...
Searching...
No Matches
convex_problem.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
9
10namespace convex {
11
19template <AtomLike Var>
20constexpr auto make_problem(const Var& x) {
22 const auto builder = conic::create_empty_cblk_builder<Space>();
23 const auto new_builder = x.template add_var_block<AtomType::VAR>(builder);
25}
26
41template <conic::BuilderLike Builder, StageType Stage>
44 using T = linalg::space_type_t<conic::builder_dom_t<Builder>>;
45
51 constexpr explicit ConvexProblem(const Builder& builder_in)
53
63 template <AtomLike Atom>
64 constexpr auto in_set(const Atom& atom) const {
65 if constexpr (!(is_set_type_v<Atom> || is_cap_type_v<Atom>))
66 static_assert(false, "Atom is not a set type");
67 else {
68 const auto new_builder =
72 }
73 }
74
82 template <InequalityType IType, AtomLike LHS, typename RHS>
88
94 constexpr auto feasibility() const {
95 const auto cb = builder.cb;
96 static constexpr std::size_t ConeN =
97 linalg::mat_cols_v<decltype(cb.map.linear_part())>;
98 static constexpr std::size_t EqN =
99 linalg::mat_cols_v<decltype(builder.eq_map.linear_part())>;
100 static constexpr std::size_t AugN = (ConeN > EqN) ? ConeN : EqN;
101 linalg::RowVector<T, AugN> c{};
102 affine::AffineMap<decltype(c)> new_map(c);
103
104 const auto new_builder = conic::make_builder<conic::builder_dom_t<Builder>>(
105 new_map, cb, builder.eq_map, builder.canonical_trace);
108 }
109
117 template <AtomLike Atom>
118 constexpr auto minimize(const Atom& atom) const {
119 if constexpr (is_set_type_v<Atom> || is_cap_type_v<Atom>) {
120 static_assert(false,
121 "Attempting to minimize a set or intersection of sets");
122 } else if constexpr (is_var_type_v<Atom>) {
123 static_assert(
124 false,
125 "Attempting to minimize over a var type, please use affine op, "
126 "convex function, or index of var instead of raw type");
127 } else if constexpr (is_index_type_v<Atom>) {
128 const auto cb = builder.cb;
129 static constexpr std::size_t ConeN =
130 linalg::mat_cols_v<decltype(cb.map.linear_part())>;
131 static constexpr std::size_t EqN =
132 linalg::mat_cols_v<decltype(builder.eq_map.linear_part())>;
133 static constexpr std::size_t AugN = (ConeN > EqN) ? ConeN : EqN;
134 linalg::RowVector<T, AugN> c{};
135 auto b = builder.coord_map.translation()(0) + atom.map.translation()(0);
136 static constexpr std::size_t N =
137 linalg::space_dim_v<conic::builder_dom_t<Builder>>;
138 constexpr std::size_t CopyN = (N < AugN) ? N : AugN;
139 for (std::size_t i = 0; i < CopyN; ++i)
140 c(0, i) = atom.map.linear_part()(0, i);
141 const affine::AffineMap<decltype(c)> new_map(c, b);
142 const auto new_builder =
143 conic::make_builder<conic::builder_dom_t<Builder>>(
144 new_map, cb, builder.eq_map, builder.canonical_trace);
147 } else {
148 static constexpr CurvatureType Tag = meta_curv_v<atom_meta_t<Atom>>;
149 if constexpr (Tag == CurvatureType::CONCAVE) {
150 static_assert(false, "Attempting to minimize a concave function");
151 } else {
152 const auto obj_builder =
154 static constexpr std::size_t ConeN =
155 linalg::mat_cols_v<decltype(obj_builder.cb.map.linear_part())>;
156 static constexpr std::size_t EqN =
157 linalg::mat_cols_v<decltype(obj_builder.eq_map.linear_part())>;
158 static constexpr std::size_t FullN = (ConeN > EqN) ? ConeN : EqN;
159 static constexpr std::size_t ObjN =
160 linalg::mat_cols_v<decltype(obj_builder.coord_map.linear_part())>;
161
162 linalg::RowVector<T, FullN> c{};
163 constexpr std::size_t CopyN = (ObjN < FullN) ? ObjN : FullN;
164 for (std::size_t i = 0; i < CopyN; ++i)
165 c(0, i) = obj_builder.coord_map.linear_part()(0, i);
166
167 const auto b = obj_builder.coord_map.translation()(0);
168 const auto obj_map = affine::AffineMap<decltype(c)>(c, b);
169 const auto new_builder =
171 obj_map, obj_builder.cb, obj_builder.eq_map,
172 obj_builder.canonical_trace);
175 }
176 }
177 }
178
186 template <AtomLike Atom>
187 constexpr auto maximize(const Atom& atom) const {
188 if constexpr (is_set_type_v<Atom> || is_cap_type_v<Atom>) {
189 static_assert(false,
190 "Attempting to maximize a set or intersection of sets");
191 } else if constexpr (is_var_type_v<Atom>) {
192 static_assert(
193 false,
194 "Attempting to maximize over a var type, please use affine op, "
195 "concave function, or index of var instead of raw type");
196 } else {
197 static constexpr CurvatureType Tag = meta_curv_v<atom_meta_t<Atom>>;
198 if constexpr (Tag == CurvatureType::CONVEX) {
199 static_assert(false, "Attempting to maximize a convex function");
200 } else {
202 return minimize(atom.template mul<-1.0>());
203 else return minimize(atom.mul(-1.0));
204 }
205 }
206 }
207
213 constexpr bool validate() const { return builder.cb.validate(); }
214
222 constexpr auto linear_objective() const
224 {
225 return linalg::as_vector(builder.coord_map.linear_part());
226 }
227
235 constexpr auto constraint_map() const
237 {
238 return builder.cb.map;
239 }
240
246 constexpr auto constraint_cones() const
248 {
249 return builder.cb.cones;
250 }
251
259 constexpr auto equality_map() const
261 {
262 return builder.eq_map;
263 }
264
275 constexpr auto canonical_trace() const
277 {
278 return builder.canonical_trace;
279 }
280
282 Builder builder;
283};
284
285} // namespace convex
constexpr auto make_builder(const CoordMap &coord_map, const CB &cb, const EqMap &eq_map, const CanonicalTrace &canonical_trace={})
Construct a canonical-form builder while deducing all realized component types (aside from dec var do...
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 std::size_t dom_size_v
CurvatureType
Curvature annotation for atom codomain.
constexpr auto make_problem(const Var &x)
make problem
StageType
Problem construction lifecycle stage.
CRTP base for convex atoms.
Definition atom.hpp:22
constexpr ConvexProblem(const Builder &builder_in)
CTOR.
constexpr auto add_constraint(const Inequality< IType, LHS, RHS > &ineq) const
add ineq constraint
constexpr bool validate() const
validate
Builder builder
member var
constexpr auto canonical_trace() const
Structural trace of canonical rows emitted during canonicalization.
constexpr auto constraint_map() const
constraint map (canonical conic form) [ F; g ]
constexpr auto in_set(const Atom &atom) const
in set constraint
constexpr auto linear_objective() const
linear objective
linalg::space_type_t< conic::builder_dom_t< Builder > > T
alias for scalar type
constexpr auto equality_map() const
affine equality map [ A; b ]
constexpr auto minimize(const Atom &atom) const
minimize
constexpr auto constraint_cones() const
cones
constexpr auto feasibility() const
feasibility
constexpr auto maximize(const Atom &atom) const
maximize
forward declaration of inequality