akreon-convex
Typed convex modeling, conic canonicalization, and primal-dual optimization in C++26.
Loading...
Searching...
No Matches
square.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
11
12namespace convex {
13
15template <linalg::RnSpace Space>
16 requires(linalg::space_dim_v<Space> == 1)
18
20template <linalg::RnSpace Space>
21 requires(linalg::space_dim_v<Space> == 1)
23
25template <linalg::RnSpace Space>
26 requires(linalg::space_dim_v<Space> == 1)
28
30template <linalg::RnSpace Space>
33
35template <linalg::RnSpace Space>
39
45template <typename Meta, typename Child>
46 requires(dom_size_v<meta_dom_t<Meta>> == 1)
47struct Square : Atom<Meta, Square<Meta, Child>, Child> {
50 using ConvexBase::N;
53
56
58 static constexpr CurvatureType Tag = meta_curv_v<Meta>;
59
65 constexpr explicit Square(const Child& child_in)
67 }
68
75 constexpr explicit Square(const Child& child_in,
76 const affine::AffineMap<LiftedVarMat<T>>& map_in)
77 : ConvexBase(child_in), lift_map(map_in) {}
78
84 constexpr MonotonicityType monotonicity() const {
85 static constexpr VarType sign =
87 if constexpr (Tag == CurvatureType::CONVEX) {
88 if constexpr (sign == VarType::NONNEG) {
90 } else if constexpr (sign == VarType::NONPOS) {
92 } else {
94 }
95 } else {
96 if constexpr (sign == VarType::NONNEG) {
98 } else if constexpr (sign == VarType::NONPOS) {
100 } else {
102 }
103 }
104 }
105
113 constexpr T operator()(const PointT& x) const { return eval(x); }
114
122 constexpr T eval(const PointT& x) const {
123 const auto alpha = lift_map.linear_part()(0, 0);
124 const auto beta = lift_map.translation()(0);
125 if constexpr (Tag == CurvatureType::CONVEX)
126 return alpha * x(0) * x(0) + beta;
127 else return T(-1) * alpha * x(0) * x(0) + beta;
128 }
129
135 template <T Scalar>
136 constexpr auto mul() const {
137 if constexpr (Scalar < T(0)) {
138 const auto alpha = T(-1) * Scalar;
139 affine::AffineMap<LiftedVarMat<T>> new_map(alpha * lift_map.linear_part(),
140 lift_map.translation());
141 if constexpr (Tag == CurvatureType::CONCAVE) {
142 return Square<SquareMeta<Space>, Child>(std::get<0>(this->children),
143 new_map);
144 } else {
146 std::get<0>(this->children), new_map);
147 }
148 } else {
149 affine::AffineMap<LiftedVarMat<T>> new_map(
150 Scalar * lift_map.linear_part(), lift_map.translation());
151 return Square<Meta, Child>(std::get<0>(this->children), new_map);
152 }
153 }
154
162 constexpr auto add(T beta) const {
163 LiftedVarBias<T> bias{beta + lift_map.translation()(0)};
164 affine::AffineMap<LiftedVarMat<T>> new_map(lift_map.linear_part(), bias);
165 return Square<Meta, Child>(std::get<0>(this->children), new_map);
166 }
167
194 template <AtomType Type, conic::BuilderLike Builder>
195 constexpr auto canonicalize_impl(const Builder& builder) const {
196 const auto child_builder =
197 std::get<0>(this->children)
198 .template canonicalize<AtomType::FN>(builder);
199 const auto child_coord = child_builder.coord_map;
200
201 using AffineMatT = affine::affine_mat_t<decltype(child_coord)>;
202 static constexpr std::size_t Dom = linalg::mat_cols_v<AffineMatT>;
203 static constexpr std::size_t Codom = linalg::mat_rows_v<AffineMatT>;
204 static_assert(Codom == 1,
205 "input affine map from cone block has invalid codom dim for "
206 "scalar fn domain (i.e., != 1");
207 linalg::Matrix<T, 3, Dom + 1> F{};
208 F = linalg::set_block<0, 1, 0, Dom>(F, child_coord.linear_part());
209 linalg::Vector<T, 3> g{};
210 g(0) = child_coord.translation()(0);
211 g(1) = T(0.5);
212
213 if constexpr (Tag == CurvatureType::CONVEX) {
214 F(2, Dom) = T(1);
215 } else {
216 F(2, Dom) = T(-1);
217 }
218
219 const auto rsoc_coords = affine::AffineMap<decltype(F)>(F, g);
220 const auto coord_map_up =
223 const auto cones = std::make_tuple(rsoc);
224 const auto emission =
226
227 return child_builder.template realize<Type>(idx, lift_map, emission);
228 }
229
231 affine::AffineMap<LiftedVarMat<T>> lift_map;
232 const int idx{-1};
233};
234
235template <typename Child>
239
240} // namespace convex
VarType
Domain/variable annotation attached to domains/codomains.
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.
linalg::remove_cvref_t< T > atom_decay_t
normalize atom-facing types to a stable internal form.
MonotonicityType
Monotonicity annotation for function atoms.
linalg::Vector< T, 1 > LiftedVarBias
alias for lifted var map
linalg::RowVector< T, 1 > LiftedVarMat
alias for lifted var map
Atom-local canonical emission bundle.
RSOC -> SOC.
Definition soc.hpp:40
forward decl for soc
Definition soc.hpp:128
CRTP base for convex atoms.
Definition atom.hpp:22
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
Atom metadata bundling domain, codomain, and curvature.
Domain wrapper with a static sign label.
forward declaration - square fn
Definition square.hpp:47
constexpr Square(const Child &child_in, const affine::AffineMap< LiftedVarMat< T > > &map_in)
CTOR.
Definition square.hpp:75
dom_space_t< meta_dom_t< Meta > > Space
alias to extract space type
Definition square.hpp:55
constexpr auto canonicalize_impl(const Builder &builder) const
canonicalize_impl
Definition square.hpp:195
constexpr auto mul() const
mul
Definition square.hpp:136
constexpr auto add(T beta) const
add
Definition square.hpp:162
constexpr T operator()(const PointT &x) const
eval via operator overload
Definition square.hpp:113
constexpr T eval(const PointT &x) const
eval impl
Definition square.hpp:122
affine::AffineMap< LiftedVarMat< T > > lift_map
member vars
Definition square.hpp:231
constexpr Square(const Child &child_in)
CTOR.
Definition square.hpp:65
constexpr MonotonicityType monotonicity() const
mono
Definition square.hpp:84