akreon-convex
Typed convex modeling, conic canonicalization, and primal-dual optimization in C++26.
Loading...
Searching...
No Matches
cone.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 <climits>
9#include <optional>
10
12#include "akreon/linalg/operator/hessian.hpp"
13#include "akreon/linalg/operator/ldl.hpp"
14
15namespace conic {
16
18template <linalg::VectorContainer Slack, typename Derived, ConeType CType>
19struct Cone {
21 using T = linalg::vector_element_t<Slack>;
22
24 static constexpr std::size_t M = linalg::vector_dim_v<Slack>;
25
27 static constexpr T eps = 1e-8;
28
30 using HessianMat = linalg::Matrix<T, M, M>;
31
39 constexpr Slack x0() const { return self().x0_impl(); }
40
48 constexpr Slack y0() const { return self().y0_impl(); }
49
59 constexpr bool in_cone(const Slack& x) const {
60 return self().in_cone_impl(x);
61 }
62
72 constexpr bool in_dual_cone(const Slack& y) const {
73 return self().in_dual_cone_impl(y);
74 }
75
84 constexpr auto H(const Slack& x, const Slack& y) const {
85 return self().H_impl(x, y);
86 }
87
102 constexpr T alpha_max(const Slack& x, const linalg::Vector<T, M>& p) const {
103 return self().alpha_max_impl(x, p);
104 }
105
120 constexpr T alpha_max_dual(const Slack& y,
121 const linalg::Vector<T, M>& p) const {
122 return self().alpha_max_dual_impl(y, p);
123 }
124
132 constexpr T nu() const { return self().nu_impl(); }
133
143 constexpr auto grad(const Slack& x) const { return self().grad_impl(x); }
144
152 constexpr auto e() const {
153 static_assert(ConeType::SYMMETRIC == CType,
154 "Nonsymmetric cone is not equipped with Jordan Algebras");
155 return self().e_impl();
156 }
157
166 constexpr auto w(const Slack& x, const Slack& y) const {
167 static_assert(ConeType::SYMMETRIC == CType,
168 "Nonsymmetric cone is not equipped with Jordan Algebras");
169 return self().w_impl(x, y);
170 }
171
180 constexpr auto circ(const Slack& x, const Slack& y) const {
181 static_assert(ConeType::SYMMETRIC == CType,
182 "Nonsymmetric cone is not equipped with Jordan Algebras");
183 return self().circ_impl(x, y);
184 }
185
194 constexpr auto trace(const Slack& x, const Slack& y) const {
195 static_assert(ConeType::SYMMETRIC == CType,
196 "Nonsymmetric cone is not equipped with Jordan Algebras");
197 return self().trace_impl(x, y);
198 }
199
207 constexpr auto inv(const Slack& x) const {
208 static_assert(ConeType::SYMMETRIC == CType,
209 "Nonsymmetric cone is not equipped with Jordan Algebras");
210 return self().inv_impl(x);
211 }
212
226 constexpr T trace_weight() const {
227 const auto identity = e();
228 return trace(identity, identity) /
229 linalg::inner_product(identity, identity);
230 }
231
245 template <typename Scaling>
246 constexpr auto scaled_affine_correction(const Slack& x, const Scaling& P,
247 const Slack& px,
248 const Slack& py) const {
249 static_assert(ConeType::SYMMETRIC == CType,
250 "NT correction requires a symmetric cone");
251 return self().scaled_affine_correction_impl(x, P, px, py);
252 }
253
255 template <typename Scaling>
256 constexpr auto scaled_affine_correction_impl(const Slack& x, const Scaling& P,
257 const Slack& px,
258 const Slack& py) const {
259 const auto [root, root_event] = self().sqrt_impl(P.x);
260 if (linalg::is_fatal_event(root_event))
261 return std::tuple(Slack{}, root_event);
262 const auto [inv_root, inv_event] = inv(root);
263 if (linalg::is_fatal_event(inv_event))
264 return std::tuple(Slack{}, inv_event);
265 const auto W_inv = Scaling(root);
266 const auto W = Scaling(inv_root);
267 const auto lambda = W_inv.apply(x);
268 HessianMat jordan{};
269 for (std::size_t j = 0; j < M; ++j) {
270 Slack basis{};
271 basis(j) = T(1);
272 const auto column = circ(lambda, basis);
273 for (std::size_t i = 0; i < M; ++i) jordan(i, j) = column(i);
274 }
275 const auto [correction, event] =
276 linalg::LDL(jordan).solve(circ(W_inv.apply(px), W.apply(py)));
277 if (linalg::is_fatal_event(event)) return std::tuple(Slack{}, event);
278 return std::tuple(W_inv.apply(correction), event);
279 }
280
289 constexpr auto gamma_F(const Slack& x, const Slack& y) const {
290 static_assert(ConeType::SYMMETRIC == CType,
291 "Nonsymmetric cone is not equipped with Jordan Algebras");
292 return self().gamma_F_impl(x, y);
293 }
294
300 constexpr auto self() const { return static_cast<const Derived&>(*this); }
301};
302
303} // namespace conic
cone base class
Definition cone.hpp:19
constexpr auto gamma_F(const Slack &x, const Slack &y) const
gamma_F (functional proximity neighborhood metric)
Definition cone.hpp:289
static constexpr std::size_t M
helpers to get M slack size
Definition cone.hpp:24
constexpr auto circ(const Slack &x, const Slack &y) const
circ (jordan map/product operator)
Definition cone.hpp:180
constexpr T trace_weight() const
Convert Euclidean complementarity to this cone's Jordan trace units.
Definition cone.hpp:226
linalg::Matrix< T, M, M > HessianMat
hessian type
Definition cone.hpp:30
linalg::vector_element_t< Slack > T
alias for mat type
Definition cone.hpp:21
constexpr auto w(const Slack &x, const Slack &y) const
w (self-scaling point)
Definition cone.hpp:166
constexpr auto scaled_affine_correction(const Slack &x, const Scaling &P, const Slack &px, const Slack &py) const
Affine second-order correction in dual coordinates under NT scaling.
Definition cone.hpp:246
constexpr bool in_dual_cone(const Slack &y) const
in the interior of K^*
Definition cone.hpp:72
constexpr auto e() const
e (jordan identity)
Definition cone.hpp:152
constexpr T alpha_max_dual(const Slack &y, const linalg::Vector< T, M > &p) const
fraction to boundary dk^*
Definition cone.hpp:120
constexpr auto scaled_affine_correction_impl(const Slack &x, const Scaling &P, const Slack &px, const Slack &py) const
Common symmetric-cone implementation using Jordan operations.
Definition cone.hpp:256
static constexpr T eps
eps constant
Definition cone.hpp:27
constexpr T nu() const
barrier parameter
Definition cone.hpp:132
constexpr auto trace(const Slack &x, const Slack &y) const
trace
Definition cone.hpp:194
constexpr Slack y0() const
default interior point (initial slack in dual cone)
Definition cone.hpp:48
constexpr auto grad(const Slack &x) const
gradient
Definition cone.hpp:143
constexpr auto self() const
self function which returns a const ref to the derived object
Definition cone.hpp:300
constexpr auto H(const Slack &x, const Slack &y) const
hessian
Definition cone.hpp:84
constexpr T alpha_max(const Slack &x, const linalg::Vector< T, M > &p) const
fraction to boundary dk
Definition cone.hpp:102
constexpr Slack x0() const
default interior point (initial slack in cone space)
Definition cone.hpp:39
constexpr auto inv(const Slack &x) const
inv (jordan inverse element)
Definition cone.hpp:207
constexpr bool in_cone(const Slack &x) const
in the interior of k
Definition cone.hpp:59