9#include "akreon/linalg/operator/quadratic_rep.hpp"
18template <linalg::VectorContainer Vec>
21 using T = linalg::vector_element_t<Vec>;
22 static constexpr std::size_t
N = linalg::vector_dim_v<Vec>;
34 constexpr auto operator()(
const Vec& x,
const Vec& y)
const {
36 for (std::size_t i = 0; i <
N; ++i) res(i) = x(i) * y(i);
45template <linalg::VectorContainer Slack>
47 :
public Cone<Slack, NonnegOrthantCone<Slack>, ConeType::SYMMETRIC> {
64 for (std::size_t i = 0; i <
M; ++i) s(i) =
T(1);
83 for (std::size_t i = 0; i <
M; ++i)
84 if (!(x(i) >
T(0)))
return false;
115 const linalg::Vector<T, M>& p)
const {
116 constexpr T eta{0.99};
118 for (std::size_t i = 0; i <
M; ++i) {
120 const T cand = -x(i) / p(i);
121 a = (cand < a) ? cand : a;
124 return std::min(
T(1), eta * a);
136 const linalg::Vector<T, M>& p)
const {
156 constexpr auto H_impl(
const Slack& x,
const Slack& y)
const {
157 const auto [
w, event] =
w_impl(x, y);
158 if (linalg::is_fatal_event(event))
162 bool safeguarded =
false;
163 for (std::size_t i = 0; i <
M; ++i) {
164 const T wi_safe = std::max(
w(i),
eps);
165 safeguarded = safeguarded || (wi_safe !=
w(i));
166 w_inv(i) =
T(1) / wi_safe;
168 const auto out_event =
169 linalg::is_fatal_event(event) ? event
170 : (
event != linalg::NumericalEvent::NONE || safeguarded)
171 ? linalg::NumericalEvent::NUMERICAL_SAFEGUARD
172 : linalg::NumericalEvent::NONE;
188 bool safeguarded =
false;
189 for (std::size_t i = 0; i <
M; ++i) {
190 const T xi_safe = std::max(x(i),
eps);
191 safeguarded = safeguarded || (xi_safe != x(i));
192 dx(i) =
T(-1) / xi_safe;
194 return std::tuple(dx, safeguarded
195 ? linalg::NumericalEvent::NUMERICAL_SAFEGUARD
196 : linalg::NumericalEvent::NONE);
214 linalg::vector_traits<Slack> vec{};
215 return vec.fill(
T(1));
226 constexpr auto w_impl(
const Slack& x,
const Slack& y)
const {
228 bool safeguarded{
false};
229 for (std::size_t i = 0; i <
M; ++i) {
230 const T x_safe = std::max(x(i),
eps);
231 const T y_safe = std::max(y(i),
eps);
232 safeguarded = safeguarded || (x_safe != x(i)) || (y_safe != y(i));
233 w(i) = linalg::constexpr_sqrt_safe(x_safe / y_safe);
235 return std::tuple(
w, safeguarded
236 ? linalg::NumericalEvent::NUMERICAL_SAFEGUARD
237 : linalg::NumericalEvent::NONE);
250 constexpr auto circ_impl(
const Slack& x,
const Slack& y)
const {
264 template <
typename Scaling>
267 const Slack& py)
const {
269 bool safeguarded =
false;
270 for (std::size_t i = 0; i <
M; ++i) {
271 const T xi_safe = std::max(x(i),
eps);
272 safeguarded = safeguarded || (xi_safe != x(i));
273 correction(i) = px(i) * py(i) * (
T(1) / xi_safe);
275 return std::tuple(correction,
276 safeguarded ? linalg::NumericalEvent::NUMERICAL_SAFEGUARD
277 : linalg::NumericalEvent::NONE);
290 constexpr auto trace_impl(
const Slack& x,
const Slack& y)
const {
293 for (std::size_t i = 0; i <
M; ++i) res += x_circ_y(i);
306 bool safeguarded =
false;
307 for (std::size_t i = 0; i <
M; ++i) {
308 const T xi_safe = std::max(x(i),
eps);
309 safeguarded = safeguarded || (xi_safe != x(i));
310 res(i) =
T(1) / xi_safe;
312 return std::tuple(res, safeguarded
313 ? linalg::NumericalEvent::NUMERICAL_SAFEGUARD
314 : linalg::NumericalEvent::NONE);
327 bool safeguarded =
false;
328 for (std::size_t i = 0; i <
M; ++i) {
329 const auto xy_safe = std::max(x(i) * y(i),
eps);
330 safeguarded = safeguarded || (xy_safe != x(i) * y(i));
331 res += linalg::constexpr_ln_safe(xy_safe,
eps);
333 const auto xTy_safe =
334 std::max(linalg::inner_product(x, y),
eps) /
nu_impl();
336 safeguarded || (xTy_safe *
nu_impl() != linalg::inner_product(x, y));
337 res =
nu_impl() * linalg::constexpr_ln_safe(xTy_safe,
eps) - res;
338 return std::tuple(res, safeguarded
339 ? linalg::NumericalEvent::NUMERICAL_SAFEGUARD
340 : linalg::NumericalEvent::NONE);
static constexpr std::size_t M
helpers to get M slack size
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)
static constexpr T eps
eps constant
forward decl for nonneg orthant cone
constexpr bool in_dual_cone_impl(const Slack &y) const
in interior of K^*
constexpr T alpha_max_impl(const Slack &x, const linalg::Vector< T, M > &p) const
fraction to boundary dK
constexpr auto trace_impl(const Slack &x, const Slack &y) const
trace
constexpr auto inv_impl(const Slack &x) const
jordan inverse
constexpr auto e_impl() const
e (jordan identity)
constexpr T nu_impl() const
barrier parameter
constexpr auto grad_impl(const Slack &x) const
grad
constexpr auto circ_impl(const Slack &x, const Slack &y) const
circ
constexpr auto gamma_F_impl(const Slack &x, const Slack &y) const
gamma_F
constexpr T alpha_max_dual_impl(const Slack &y, const linalg::Vector< T, M > &p) const
fracto to dK^*
constexpr auto w_impl(const Slack &x, const Slack &y) const
w (self-scaled point)
constexpr auto H_impl(const Slack &x, const Slack &y) const
hessian
constexpr auto scaled_affine_correction_impl(const Slack &x, const Scaling &, const Slack &px, const Slack &py) const
Componentwise form of the NT-scaled affine correction for R^n_+.
constexpr bool in_cone_impl(const Slack &x) const
in interior of K
constexpr Slack y0_impl() const
default dual point
constexpr Slack x0_impl() const
default interior point
Circ - Jordan Map/Product for R^n_+.
constexpr auto operator()(const Vec &x, const Vec &y) const
circ (jordan map/product)
linalg::vector_element_t< Vec > T
types and size extraction
static constexpr std::size_t N