akreon-convex
Typed convex modeling, conic canonicalization, and primal-dual optimization in C++26.
Loading...
Searching...
No Matches
kl_div.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 "akreon/linalg/assert.hpp"
11
12namespace convex {
13
15template <linalg::RnSpace Space>
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 Dom, linalg::RnSpace Codom>
30using KLDivMeta =
32
34template <linalg::RnSpace Dom, linalg::RnSpace Codom>
37
45template <typename Meta, typename Child>
46struct KLDivergence : Atom<Meta, KLDivergence<Meta, Child>, Child> {
49 using ConvexBase::N;
52
55
62 constexpr explicit KLDivergence(const PointT& p_in, const Child& child_in)
65 for (const auto& x : p) {
66 AK_ASSERT(x > T(0) &&
67 "KLDivergence expects each fixed p entry to satisfy x > 0");
68 (void)x;
69 }
70 }
71
79 constexpr explicit KLDivergence(
80 const PointT& p_in, const Child& child_in,
81 const affine::AffineMap<LiftedVarMat<T>>& map_in)
83 for (const auto& x : p) {
84 AK_ASSERT(x > T(0) &&
85 "KLDivergence expects each fixed p entry to satisfy x > 0");
86 (void)x;
87 }
88 }
89
95 constexpr MonotonicityType monotonicity() const {
97 }
98
107 constexpr T operator()(const PointT& q) const { return eval(q); }
108
117 constexpr T eval(const PointT& q) const {
118 T res(0);
119 for (std::size_t i = 0; i < N; ++i) {
120 AK_ASSERT(p(i) >= T(0) && q(i) > T(0) && "Invalid domain for kl div");
121 res += p(i) * linalg::constexpr_ln(p(i) / q(i)).value();
122 }
123
124 if constexpr (Tag == CurvatureType::CONVEX) return res;
125 else return T(-1) * res;
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
140 using Dom = dom_space_t<meta_dom_t<Meta>>;
141 using Codom = dom_space_t<meta_codom_t<Meta>>;
142 if constexpr (Tag == CurvatureType::CONCAVE) {
144 p, std::get<0>(this->children), new_map);
145 } else {
147 p, std::get<0>(this->children), new_map);
148 }
149 } else {
150 affine::AffineMap<LiftedVarMat<T>> new_map(
151 Scalar * lift_map.linear_part(), lift_map.translation());
152 return KLDivergence<Meta, Child>(p, std::get<0>(this->children), new_map);
153 }
154 }
155
163 constexpr auto add(T beta) const {
164 LiftedVarBias<T> bias{beta + lift_map.translation()(0)};
165 affine::AffineMap<LiftedVarMat<T>> new_map(lift_map.linear_part(), bias);
166 return KLDivergence<Meta, Child>(p, std::get<0>(this->children), new_map);
167 }
168
201 template <AtomType Type, conic::BuilderLike Builder>
202 constexpr auto canonicalize_impl(const Builder& builder) const {
203 const auto child_builder =
204 std::get<0>(this->children)
205 .template canonicalize<AtomType::FN>(builder);
206 const auto child_coord = child_builder.coord_map;
207
208 using AffineMatT = affine::affine_mat_t<decltype(child_coord)>;
209 static constexpr std::size_t Dom = linalg::mat_cols_v<AffineMatT>;
210 static constexpr std::size_t Codom = linalg::mat_rows_v<AffineMatT>;
211 static_assert(Codom == N,
212 "Input affine map from cone block has invalid dom which is a "
213 "mismatch between domain in the convex function");
214 static_assert(Dom == N,
215 "Expecting child affine map to have square linear part");
216 linalg::Matrix<T, 3 * N + 1, 3 * N + 1> F;
217 linalg::Vector<T, 3 * N + 1> g;
218 for (std::size_t i = 0; i < N; ++i)
219 g(2 * N + i) = child_coord.translation()(i);
220
221 const auto I = linalg::make_identity<T, N>();
222 if constexpr (Tag == CurvatureType::CONVEX)
223 F = linalg::set_block<0, N, 2 * N, 3 * N>(F, T(-1) * I);
224 else F = linalg::set_block<0, N, 2 * N, 3 * N>(F, I);
225
226 F = linalg::set_block<N, 2 * N, 0, N>(F, I);
227 F = linalg::set_block<2 * N, 3 * N, N, 2 * N>(F, child_coord.linear_part());
228 for (std::size_t i = 0; i < N; ++i) F(3 * N, 2 * N + i) = T(-1);
229 F(3 * N, 3 * N) = T(1);
230
231 const auto coord_map_up = affine::AffineMap<decltype(F)>(F, g);
234 const auto cones = std::make_tuple(exp_cone, rplus);
235 const auto emission =
237
239 }
240
243 affine::AffineMap<LiftedVarMat<T>> lift_map;
244 const int idx{-1};
245};
246
247template <typename Point, typename Child>
248KLDivergence(const Point&, const Child&) -> KLDivergence<
249 KLDivMeta<
251 linalg::Matrix<dom_type_t<meta_codom_t<atom_meta_t<Child>>>, 1, 1>>,
253
254} // namespace convex
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
forward decl for exp
Definition exp_cone.hpp:25
Atom-local canonical emission bundle.
forward decl for nonneg orthant cone
Definition rplus.hpp:47
CRTP base for convex atoms.
Definition atom.hpp:22
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 - kl divergence
Definition kl_div.hpp:46
constexpr T eval(const PointT &q) const
eval impl
Definition kl_div.hpp:117
constexpr MonotonicityType monotonicity() const
mono
Definition kl_div.hpp:95
constexpr KLDivergence(const PointT &p_in, const Child &child_in, const affine::AffineMap< LiftedVarMat< T > > &map_in)
CTOR.
Definition kl_div.hpp:79
constexpr auto mul() const
mul
Definition kl_div.hpp:134
static constexpr CurvatureType Tag
curvature tag
Definition kl_div.hpp:54
constexpr T operator()(const PointT &q) const
eval via operator overload
Definition kl_div.hpp:107
PointT p
member vars
Definition kl_div.hpp:242
affine::AffineMap< LiftedVarMat< T > > lift_map
Definition kl_div.hpp:243
constexpr KLDivergence(const PointT &p_in, const Child &child_in)
CTOR.
Definition kl_div.hpp:62
constexpr auto canonicalize_impl(const Builder &builder) const
canonicalize impl
Definition kl_div.hpp:202
constexpr auto add(T beta) const
add
Definition kl_div.hpp:163