akreon-convex
Typed convex modeling, conic canonicalization, and primal-dual optimization in C++26.
Loading...
Searching...
No Matches
abs.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
10
11namespace convex {
12
14template <linalg::RnSpace Space>
15 requires(linalg::space_dim_v<Space> == 1)
17
19template <linalg::RnSpace Space>
20 requires(linalg::space_dim_v<Space> == 1)
22
24template <linalg::RnSpace Space>
25 requires(linalg::space_dim_v<Space> == 1)
27
29template <linalg::RnSpace Space>
30using AbsMeta =
32
34template <linalg::RnSpace Space>
37
43template <typename Meta, typename Child>
44 requires(dom_size_v<meta_dom_t<Meta>> == 1)
45struct Abs : Atom<Meta, Abs<Meta, Child>, Child> {
48 using ConvexBase::N;
51
54
56 static constexpr CurvatureType Tag = meta_curv_v<Meta>;
57
63 constexpr explicit Abs(const Child& child_in)
65 }
66
73 constexpr explicit Abs(const Child& child_in,
74 const affine::AffineMap<LiftedVarMat<T>>& map_in)
75 : ConvexBase(child_in), lift_map(map_in) {}
76
82 constexpr MonotonicityType monotonicity() const {
83 static constexpr VarType sign =
85 if constexpr (Tag == CurvatureType::CONVEX) {
86 if constexpr (sign == VarType::NONNEG) {
88 } else if constexpr (sign == VarType::NONPOS) {
90 } else {
92 }
93 } else {
94 if constexpr (sign == VarType::NONNEG) {
96 } else if constexpr (sign == VarType::NONPOS) {
98 } else {
100 }
101 }
102 }
103
111 constexpr T operator()(const PointT& x) const { return eval(x); }
112
120 constexpr T eval(const PointT& x) const {
121 const auto alpha = lift_map.linear_part()(0, 0);
122 const auto beta = lift_map.translation()(0);
123 if constexpr (Tag == CurvatureType::CONVEX)
124 return alpha * linalg::constexpr_abs(x(0)) + beta;
125 else return T(-1) * alpha * linalg::constexpr_abs(x(0)) + beta;
126 }
127
133 template <T Scalar>
134 constexpr auto mul() const {
135 if constexpr (Scalar < T(0)) {
136 const auto alpha = T(-1) * Scalar;
137 affine::AffineMap<LiftedVarMat<T>> new_map(alpha * lift_map.linear_part(),
138 lift_map.translation());
139 if constexpr (Tag == CurvatureType::CONCAVE) {
140 return Abs<AbsMeta<Space>, Child>(std::get<0>(this->children), new_map);
141 } else {
142 return Abs<AbsConcaveMeta<Space>, Child>(std::get<0>(this->children),
143 new_map);
144 }
145 } else {
146 affine::AffineMap<LiftedVarMat<T>> new_map(
147 Scalar * lift_map.linear_part(), lift_map.translation());
148 return Abs<Meta, Child>(std::get<0>(this->children), new_map);
149 }
150 }
151
159 constexpr auto add(T beta) const {
160 LiftedVarBias<T> bias{beta + lift_map.translation()(0)};
161 affine::AffineMap<LiftedVarMat<T>> new_map(lift_map.linear_part(), bias);
162 return Abs<Meta, Child>(std::get<0>(this->children), new_map);
163 }
164
215 template <AtomType Type, conic::BuilderLike Builder>
216 constexpr auto canonicalize_impl(const Builder& builder) const {
217 const auto child_builder =
218 std::get<0>(this->children)
219 .template canonicalize<AtomType::FN>(builder);
220 const auto child_coord = child_builder.coord_map;
221
222 using AffineMatT = affine::affine_mat_t<decltype(child_coord)>;
223 static constexpr std::size_t Dom = linalg::mat_cols_v<AffineMatT>;
224 static constexpr std::size_t Codom = linalg::mat_rows_v<AffineMatT>;
225 static_assert(Codom == 1,
226 "input affine map from cone block has invalid codom dim for "
227 "scalar fn domain (i.e., != 1");
228 linalg::Matrix<T, 5, Dom + 2> F;
229 F = linalg::set_block<0, 1, 0, Dom>(F, child_coord.linear_part());
230 F = linalg::set_block<1, 2, 0, Dom>(F, T(-1) * child_coord.linear_part());
231 F(0, Dom) = T(1);
232 F(1, Dom) = T(1);
233 F(2, Dom) = T(-1);
234 F(3, Dom) = T(1);
235
236 linalg::Vector<T, 5> g;
237 g(0) = child_coord.translation()(0);
238 g(1) = T(-1) * child_coord.translation()(0);
239
240 if constexpr (Tag == CurvatureType::CONVEX) {
241 F(2, Dom + 1) = T(1);
242 F(4, Dom + 1) = T(1);
243 } else {
244 F(2, Dom + 1) = T(-1);
245 F(4, Dom + 1) = T(-1);
246 }
247
248 const auto coord_map_up = affine::AffineMap<decltype(F)>(F, g);
250 const auto cones = std::make_tuple(rplus, rplus, rplus, rplus, rplus);
251 const auto emission =
253
254 return child_builder.template realize<Type>(idx, lift_map, emission);
255 }
256
258 affine::AffineMap<LiftedVarMat<T>> lift_map;
259 const int idx{-1};
260};
261
262template <typename Child>
265
266} // 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.
forward decl for nonneg orthant cone
Definition rplus.hpp:47
forward declaration - abs fn
Definition abs.hpp:45
constexpr Abs(const Child &child_in, const affine::AffineMap< LiftedVarMat< T > > &map_in)
CTOR.
Definition abs.hpp:73
constexpr Abs(const Child &child_in)
CTOR.
Definition abs.hpp:63
constexpr auto mul() const
mul
Definition abs.hpp:134
dom_space_t< meta_dom_t< Meta > > Space
alias to extract space type
Definition abs.hpp:53
constexpr T eval(const PointT &x) const
eval impl
Definition abs.hpp:120
constexpr auto canonicalize_impl(const Builder &builder) const
canonicalize_impl
Definition abs.hpp:216
constexpr T operator()(const PointT &x) const
eval via operator overload
Definition abs.hpp:111
affine::AffineMap< LiftedVarMat< T > > lift_map
member vars
Definition abs.hpp:258
constexpr MonotonicityType monotonicity() const
mono
Definition abs.hpp:82
constexpr auto add(T beta) const
add
Definition abs.hpp:159
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.