12#include "akreon/linalg/operator/hessian.hpp"
13#include "akreon/linalg/operator/ldl.hpp"
18template <linalg::VectorContainer Slack,
typename Derived, ConeType CType>
21 using T = linalg::vector_element_t<Slack>;
24 static constexpr std::size_t
M = linalg::vector_dim_v<Slack>;
39 constexpr Slack
x0()
const {
return self().x0_impl(); }
48 constexpr Slack
y0()
const {
return self().y0_impl(); }
59 constexpr bool in_cone(
const Slack& x)
const {
60 return self().in_cone_impl(x);
73 return self().in_dual_cone_impl(y);
84 constexpr auto H(
const Slack& x,
const Slack& y)
const {
85 return self().H_impl(x, y);
102 constexpr T alpha_max(
const Slack& x,
const linalg::Vector<T, M>& p)
const {
103 return self().alpha_max_impl(x, p);
121 const linalg::Vector<T, M>& p)
const {
122 return self().alpha_max_dual_impl(y, p);
132 constexpr T nu()
const {
return self().nu_impl(); }
143 constexpr auto grad(
const Slack& x)
const {
return self().grad_impl(x); }
152 constexpr auto e()
const {
154 "Nonsymmetric cone is not equipped with Jordan Algebras");
155 return self().e_impl();
166 constexpr auto w(
const Slack& x,
const Slack& y)
const {
168 "Nonsymmetric cone is not equipped with Jordan Algebras");
169 return self().w_impl(x, y);
180 constexpr auto circ(
const Slack& x,
const Slack& y)
const {
182 "Nonsymmetric cone is not equipped with Jordan Algebras");
183 return self().circ_impl(x, y);
194 constexpr auto trace(
const Slack& x,
const Slack& y)
const {
196 "Nonsymmetric cone is not equipped with Jordan Algebras");
197 return self().trace_impl(x, y);
207 constexpr auto inv(
const Slack& x)
const {
209 "Nonsymmetric cone is not equipped with Jordan Algebras");
210 return self().inv_impl(x);
227 const auto identity =
e();
228 return trace(identity, identity) /
229 linalg::inner_product(identity, identity);
245 template <
typename Scaling>
248 const Slack& py)
const {
250 "NT correction requires a symmetric cone");
251 return self().scaled_affine_correction_impl(x, P, px, py);
255 template <
typename Scaling>
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);
269 for (std::size_t j = 0; j <
M; ++j) {
272 const auto column =
circ(lambda, basis);
273 for (std::size_t i = 0; i <
M; ++i) jordan(i, j) = column(i);
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);
289 constexpr auto gamma_F(
const Slack& x,
const Slack& y)
const {
291 "Nonsymmetric cone is not equipped with Jordan Algebras");
292 return self().gamma_F_impl(x, y);
300 constexpr auto self()
const {
return static_cast<const Derived&
>(*this); }
constexpr auto gamma_F(const Slack &x, const Slack &y) const
gamma_F (functional proximity neighborhood metric)
static constexpr std::size_t M
helpers to get M slack size
constexpr auto circ(const Slack &x, const Slack &y) const
circ (jordan map/product operator)
constexpr T trace_weight() const
Convert Euclidean complementarity to this cone's Jordan trace units.
linalg::Matrix< T, M, M > HessianMat
hessian type
linalg::vector_element_t< Slack > T
alias for mat type
constexpr auto w(const Slack &x, const Slack &y) const
w (self-scaling point)
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.
constexpr bool in_dual_cone(const Slack &y) const
in the interior of K^*
constexpr auto e() const
e (jordan identity)
constexpr T alpha_max_dual(const Slack &y, const linalg::Vector< T, M > &p) const
fraction to boundary dk^*
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.
static constexpr T eps
eps constant
constexpr T nu() const
barrier parameter
constexpr auto trace(const Slack &x, const Slack &y) const
trace
constexpr Slack y0() const
default interior point (initial slack in dual cone)
constexpr auto grad(const Slack &x) const
gradient
constexpr auto self() const
self function which returns a const ref to the derived object
constexpr auto H(const Slack &x, const Slack &y) const
hessian
constexpr T alpha_max(const Slack &x, const linalg::Vector< T, M > &p) const
fraction to boundary dk
constexpr Slack x0() const
default interior point (initial slack in cone space)
constexpr auto inv(const Slack &x) const
inv (jordan inverse element)
constexpr bool in_cone(const Slack &x) const
in the interior of k