idol
A C++ Framework for Optimization
Loading...
Searching...
No Matches
to_rotated_quadratic_cone.h
1
//
2
// Created by henri on 22/02/23.
3
//
4
5
#ifndef IDOL_TO_ROTATED_QUADRATIC_CONE_H
6
#define IDOL_TO_ROTATED_QUADRATIC_CONE_H
7
8
#ifdef IDOL_USE_EIGEN
9
10
#include "idol/mixed-integer/modeling/expressions/LinExpr.h"
11
#include "SquareMatrix.h"
12
13
namespace
idol {
14
15
/*
16
static std::list<AffExpr<Var>> to_rotated_quadratic_cone(const QuadExpr<Var> &t_expr) {
17
18
// Create index mapping
19
MatrixIndices indices;
20
21
for (const auto &[vars, constant]: t_expr) {
22
indices.add(vars.first);
23
indices.add(vars.second);
24
}
25
26
// Create quadratic form matrix s.t. quadratic_part = x^TQx
27
SquareMatrix Q(indices);
28
29
for (const auto &[vars, constant]: t_expr) {
30
if (vars.first.id() == vars.second.id()) {
31
Q.set(vars.first, vars.second, constant);
32
} else {
33
Q.set(vars.first, vars.second, constant / 2.);
34
}
35
}
36
37
// Compute Q = LDL^T decomposition
38
const auto &[L, D] = Q.eigen_decomposition();
39
40
// Search for negative eigen values
41
std::list<std::pair<Var, double>> negative_eigen_values;
42
for (const auto &[var, index]: indices.indices()) {
43
const double eigen_value = D.get(index, index);
44
if (eigen_value < 0) {
45
negative_eigen_values.emplace_back(var, eigen_value);
46
}
47
}
48
49
const unsigned int n_negative_eigen_values = negative_eigen_values.size();
50
51
if (n_negative_eigen_values > 2) {
52
throw Exception("Non-convex expression found.");
53
}
54
55
// We write x^TQx = ||Fx||^2 + x^TNx
56
57
// Compute F = sqrt( D - D^- )L^T where D^- is D without negative entries
58
auto F = D;
59
for (const auto &[var, eigen_value]: negative_eigen_values) {
60
F.set(var, var, 0);
61
}
62
F = F.sqrt() * L.transpose();
63
64
// Compute N = LD^-L^T
65
SquareMatrix N(indices);
66
for (const auto &[var, eigen_value]: negative_eigen_values) {
67
N.set(var, var, eigen_value);
68
}
69
N = L * N * L.transpose();
70
71
// Build result
72
std::list<AffExpr<Var>> result;
73
74
// Create head
75
for (const auto &[var1, i]: indices.indices()) {
76
LinExpr<Var> expr;
77
for (const auto &[var2, j]: indices.indices()) {
78
const double n_ij = N.get(i, j);
79
if (n_ij == 0) { continue; }
80
expr += LinExpr<Var>(std::sqrt(-n_ij), var2);
81
}
82
if (!expr.empty()) {
83
result.emplace_back(std::move(expr));
84
}
85
}
86
87
if (result.empty()) {
88
result.emplace_back();
89
result.emplace_back();
90
}
91
92
if (result.size() == 1) {
93
result.emplace_back(result.front());
94
}
95
96
result.front() *= .5;
97
98
if (result.size() > 2) {
99
throw Exception("Non-convex expression found.");
100
}
101
102
for (const auto &[_, i]: indices.indices()) {
103
104
LinExpr<Var> expr;
105
for (const auto &[var, j]: indices.indices()) {
106
expr += LinExpr<Var>(F.get(i, j), var);
107
}
108
109
if (!expr.empty()) {
110
result.emplace_back(std::move(expr));
111
}
112
}
113
114
return result;
115
}
116
*/
117
}
118
119
#endif
120
121
#endif
//IDOL_TO_ROTATED_QUADRATIC_CONE_H
lib
include
idol
general
linear-algebra
to_rotated_quadratic_cone.h
Generated by
1.9.8