Skip to content
This repository was archived by the owner on Aug 6, 2023. It is now read-only.

Commit 18e5d50

Browse files
committed
replace optional<> with pointer
1 parent 024808c commit 18e5d50

File tree

10 files changed

+116
-87
lines changed

10 files changed

+116
-87
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ option(INSTALL_ONLY "Enable for installation only" OFF)
1212
# Note: update this to your new project's name and version
1313
project(
1414
LmiSolver
15-
VERSION 1.3.6
15+
VERSION 1.3.7
1616
LANGUAGES CXX
1717
)
1818

bench/BM_lmi.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ static void LMI_Lazy(benchmark::State &state) {
127127
B2.row(2) = Vec{40.0, 10.0, 15.0};
128128

129129
while (state.KeepRunning()) {
130-
auto P =
131-
my_oracle<LmiOracle<Matrix>>(2, F1, B1, 3, F2, B2, Vec{1.0, -1.0, 1.0});
130+
auto P = my_oracle<LmiOracle<Vec, Matrix>>(2, F1, B1, 3, F2, B2,
131+
Vec{1.0, -1.0, 1.0});
132132
auto E = Ell<Vec>(10.0, Vec{0.0, 0.0, 0.0});
133133
auto t = 1e100; // std::numeric_limits<double>::max()
134134
[[maybe_unused]] const auto rslt = cutting_plane_optim(P, E, t);
@@ -192,8 +192,8 @@ static void LMI_old(benchmark::State &state) {
192192
B2.row(2) = Vec{40.0, 10.0, 15.0};
193193

194194
while (state.KeepRunning()) {
195-
auto P = my_oracle<LmiOldOracle<Matrix>>(2, F1, B1, 3, F2, B2,
196-
Vec{1.0, -1.0, 1.0});
195+
auto P = my_oracle<LmiOldOracle<Vec, Matrix>>(2, F1, B1, 3, F2, B2,
196+
Vec{1.0, -1.0, 1.0});
197197
auto E = Ell<Vec>(10.0, Vec{0.0, 0.0, 0.0});
198198
auto t = 1e100; // std::numeric_limits<double>::max()
199199
[[maybe_unused]] const auto rslt = cutting_plane_optim(P, E, t);

include/lmisolver/ldlt_ext.hpp

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,11 @@ class ldlt_ext {
7878
*
7979
* See also: factorize()
8080
*/
81-
template <typename Callable, bool Allow_semidefinite = false>
82-
auto factor(Callable &&getA) -> bool {
81+
template <typename Callable> auto factor(Callable &&getA) -> bool {
8382
this->p = {0U, 0U};
84-
auto &[start, stop] = this->p;
83+
// auto &[start, stop] = this->p;
84+
auto &start = this->p.first;
85+
auto &stop = this->p.second;
8586

8687
for (auto i = 0U; i != this->_n; ++i) {
8788
// auto j = start;
@@ -97,27 +98,57 @@ class ldlt_ext {
9798
}
9899
this->T(i, i) = d;
99100

100-
if constexpr (Allow_semidefinite) {
101-
if (d < 0.0) {
102-
// this->stop = i + 1;
103-
stop = i + 1;
104-
break;
105-
}
106-
if (d == 0.0) {
107-
start = i + 1;
108-
// restart at i + 1, special as an LMI oracle
109-
}
110-
} else { // not Allow_semidefinite
111-
if (d <= 0.0) {
112-
stop = i + 1;
113-
break;
114-
}
101+
if (d <= 0.0) {
102+
stop = i + 1;
103+
break;
115104
}
116105
}
117106

118107
return this->is_spd();
119108
}
120109

110+
/**
111+
* @brief Perform LDLT Factorization (Lazy evaluation)
112+
*
113+
* @tparam Fn
114+
* @param[in] getA function to access the elements of A
115+
*
116+
* See also: factorize()
117+
*/
118+
template <typename Callable>
119+
auto factor_with_allow_semidefinte(Callable &&getA) -> bool {
120+
this->p = {0U, 0U};
121+
// auto &[start, stop] = this->p;
122+
auto &start = this->p.first;
123+
auto &stop = this->p.second;
124+
125+
for (auto i = 0U; i != this->_n; ++i) {
126+
// auto j = start;
127+
auto d = getA(i, start);
128+
for (auto j = start; j != i; ++j) {
129+
this->T(j, i) = d;
130+
this->T(i, j) = d / this->T(j, j); // note: T(j, i) here!
131+
auto s = j + 1;
132+
d = getA(i, s);
133+
for (auto k = start; k != s; ++k) {
134+
d -= this->T(i, k) * this->T(k, s);
135+
}
136+
}
137+
this->T(i, i) = d;
138+
139+
if (d < 0.0) {
140+
// this->stop = i + 1;
141+
stop = i + 1;
142+
break;
143+
}
144+
if (d == 0.0) {
145+
start = i + 1;
146+
// restart at i + 1, special as an LMI oracle
147+
}
148+
}
149+
return this->is_spd();
150+
}
151+
121152
/**
122153
* @brief Is $A$ symmetric positive definite (spd)
123154
*

include/lmisolver/lmi0_oracle.hpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
// -*- coding: utf-8 -*-
22
#pragma once
33

4-
#include <gsl/span>
5-
#include <optional>
6-
74
#include "ldlt_ext.hpp"
5+
#include <gsl/span>
6+
#include <memory> // for unique_ptr
87

98
/**
109
* @brief Oracle for Linear Matrix Inequality.
@@ -14,15 +13,15 @@
1413
* find x
1514
* s.t. F * x <= 0
1615
*/
17-
template <typename Mat> class Lmi0Oracle {
18-
// using Arr = xt::xarray<double, xt::layout_type::row_major>;
19-
// using Cut = std::pair<Arr036, double>;
16+
template <typename Arr036, typename Mat = Arr036> class Lmi0Oracle {
17+
using Cut = std::pair<Arr036, double>;
2018

2119
public:
2220
ldlt_ext _Q;
2321

2422
private:
2523
const gsl::span<const Mat> _F;
24+
std::unique_ptr<Cut> cut;
2625

2726
public:
2827
/**
@@ -31,17 +30,16 @@ template <typename Mat> class Lmi0Oracle {
3130
* @param[in] F
3231
* @param[in] dim
3332
*/
34-
Lmi0Oracle(size_t dim, gsl::span<const Mat> F) : _Q(dim), _F{F} {}
33+
Lmi0Oracle(size_t dim, gsl::span<const Mat> F)
34+
: _Q(dim), _F{F}, cut{std::make_unique<Cut>()} {}
3535

3636
/**
3737
* @brief
3838
*
3939
* @param[in] x
4040
* @return std::optional<Cut>
4141
*/
42-
template <typename Arr036>
43-
auto assess_feas(const Arr036 &x)
44-
-> std::optional<std::pair<Arr036, double>> {
42+
auto assess_feas(const Arr036 &x) -> Cut * {
4543
const auto n = x.size();
4644

4745
auto getA = [&, this](size_t i, size_t j) -> double {
@@ -53,15 +51,17 @@ template <typename Mat> class Lmi0Oracle {
5351
};
5452

5553
if (this->_Q.factor(getA)) {
56-
return {};
54+
return nullptr;
5755
}
58-
auto ep = this->_Q.witness();
56+
57+
auto ep = this->_Q.witness(); // call before sym_quad() !!!
5958
Arr036 g{x};
60-
// auto g = Arr036(x.size(), 0.0);
6159
for (auto i = 0U; i != n; ++i) {
6260
g[i] = -this->_Q.sym_quad(this->_F[i]);
6361
}
64-
return {{std::move(g), ep}};
62+
cut->first = std::move(g);
63+
cut->second = std::move(ep);
64+
return cut.get();
6565
}
6666

6767
/**
@@ -70,8 +70,5 @@ template <typename Mat> class Lmi0Oracle {
7070
* @param[in] x
7171
* @return std::optional<Cut>
7272
*/
73-
template <typename Arr036>
74-
auto operator()(const Arr036 &x) -> std::optional<std::pair<Arr036, double>> {
75-
return assess_feas(x);
76-
}
73+
auto operator()(const Arr036 &x) -> Cut * { return assess_feas(x); }
7774
};
Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
// -*- coding: utf-8 -*-
22
#pragma once
33

4-
#include <gsl/span>
5-
#include <optional>
6-
74
#include "ldlt_ext.hpp"
5+
#include <gsl/span>
6+
#include <memory> // for unique_ptr
87

98
/**
109
* @brief Oracle for Linear Matrix Inequality.
@@ -14,15 +13,15 @@
1413
* find x
1514
* s.t. (B - F * x) >= 0
1615
*/
17-
template <typename Mat> class LmiOldOracle {
18-
// using Arr = xt::xarray<double, xt::layout_type::row_major>;
19-
// using Cut = std::pair<Arr036, double>;
16+
template <typename Arr036, typename Mat = Arr036> class LmiOldOracle {
17+
using Cut = std::pair<Arr036, double>;
2018

2119
private:
2220
size_t _m;
2321
ldlt_ext _Q;
2422
const gsl::span<const Mat> _F;
2523
const Mat _F0;
24+
std::unique_ptr<Cut> cut;
2625

2726
public:
2827
/**
@@ -32,17 +31,16 @@ template <typename Mat> class LmiOldOracle {
3231
* @param[in] B
3332
*/
3433
LmiOldOracle(size_t dim, gsl::span<const Mat> F, Mat B)
35-
: _m{dim}, _Q(_m), _F{F}, _F0{std::move(B)} {}
34+
: _m{dim},
35+
_Q(_m), _F{F}, _F0{std::move(B)}, cut{std::make_unique<Cut>()} {}
3636

3737
/**
3838
* @brief
3939
*
4040
* @param[in] x
4141
* @return std::optional<Cut>
4242
*/
43-
template <typename Arr036>
44-
auto assess_feas(const Arr036 &x)
45-
-> std::optional<std::pair<Arr036, double>> {
43+
auto assess_feas(const Arr036 &x) -> Cut * {
4644
const auto n = x.size();
4745

4846
Mat A{this->_F0};
@@ -55,16 +53,17 @@ template <typename Mat> class LmiOldOracle {
5553
}
5654

5755
if (this->_Q.factorize(A)) {
58-
return {};
56+
return nullptr;
5957
}
6058

61-
auto ep = this->_Q.witness();
59+
auto ep = this->_Q.witness(); // call before sym_quad() !!!
6260
Arr036 g{x};
63-
// auto g = Arr036(x.size(), 0.0);
6461
for (auto i = 0U; i != n; ++i) {
6562
g[i] = this->_Q.sym_quad(this->_F[i]);
6663
}
67-
return {{std::move(g), ep}};
64+
cut->first = std::move(g);
65+
cut->second = std::move(ep);
66+
return cut.get();
6867
}
6968

7069
/**
@@ -73,8 +72,5 @@ template <typename Mat> class LmiOldOracle {
7372
* @param[in] x
7473
* @return std::optional<Cut>
7574
*/
76-
template <typename Arr036>
77-
auto operator()(const Arr036 &x) -> std::optional<std::pair<Arr036, double>> {
78-
return assess_feas(x);
79-
}
75+
auto operator()(const Arr036 &x) -> Cut * { return assess_feas(x); }
8076
};

include/lmisolver/lmi_oracle.hpp

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
// -*- coding: utf-8 -*-
22
#pragma once
33

4-
#include <gsl/span>
5-
#include <optional>
6-
74
#include "ldlt_ext.hpp"
5+
#include <gsl/span>
6+
#include <memory> // for unique_ptr
87

98
/**
109
* @brief Oracle for Linear Matrix Inequality.
@@ -14,14 +13,14 @@
1413
* find x
1514
* s.t. (B - F * x) >= 0
1615
*/
17-
template <typename Mat> class LmiOracle {
18-
// using Arr = xt::xarray<double, xt::layout_type::row_major>;
19-
// using Cut = std::pair<Arr036, double>;
16+
template <typename Arr036, typename Mat = Arr036> class LmiOracle {
17+
using Cut = std::pair<Arr036, double>;
2018

2119
private:
2220
ldlt_ext _Q;
2321
const gsl::span<const Mat> _F;
2422
const Mat _F0;
23+
std::unique_ptr<Cut> cut;
2524

2625
public:
2726
/**
@@ -31,17 +30,15 @@ template <typename Mat> class LmiOracle {
3130
* @param[in] B
3231
*/
3332
LmiOracle(size_t dim, gsl::span<const Mat> F, Mat B)
34-
: _Q{dim}, _F{F}, _F0{std::move(B)} {}
33+
: _Q{dim}, _F{F}, _F0{std::move(B)}, cut{std::make_unique<Cut>()} {}
3534

3635
/**
3736
* @brief
3837
*
3938
* @param[in] x
4039
* @return std::optional<Cut>
4140
*/
42-
template <typename Arr036>
43-
auto assess_feas(const Arr036 &x)
44-
-> std::optional<std::pair<Arr036, double>> {
41+
auto assess_feas(const Arr036 &x) -> Cut * {
4542
const auto n = x.size();
4643

4744
auto getA = [&, this](size_t i, size_t j) -> double {
@@ -53,15 +50,17 @@ template <typename Mat> class LmiOracle {
5350
};
5451

5552
if (this->_Q.factor(getA)) {
56-
return {};
53+
return nullptr;
5754
}
58-
auto ep = this->_Q.witness();
55+
auto ep = this->_Q.witness(); // call before sym_quad() !!!
5956
Arr036 g = x;
6057
// auto g = Arr036(x.size(), 0.0);
6158
for (auto i = 0U; i != n; ++i) {
6259
g[i] = this->_Q.sym_quad(this->_F[i]);
6360
}
64-
return {{std::move(g), ep}};
61+
cut->first = std::move(g);
62+
cut->second = std::move(ep);
63+
return cut.get();
6564
}
6665

6766
/**
@@ -70,8 +69,5 @@ template <typename Mat> class LmiOracle {
7069
* @param[in] x
7170
* @return std::optional<Cut>
7271
*/
73-
template <typename Arr036>
74-
auto operator()(const Arr036 &x) -> std::optional<std::pair<Arr036, double>> {
75-
return assess_feas(x);
76-
}
72+
auto operator()(const Arr036 &x) -> Cut * { return assess_feas(x); }
7773
};

source/greeter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
#include <type_traits> // for move
88

99
using namespace lmisolver;
10-
using namespace std;
1110

12-
LmiSolver::LmiSolver(string _name) : name(move(_name)) {}
11+
LmiSolver::LmiSolver(std::string _name) : name(std::move(_name)) {}
1312

1413
auto LmiSolver::greet(LanguageCode lang) const -> std::string {
1514
switch (lang) {

test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ add_executable(${PROJECT_NAME}Tests ${sources})
1818
target_link_libraries(
1919
${PROJECT_NAME}Tests doctest::doctest ${PROJECT_NAME}::${PROJECT_NAME} ${SPECIFIC_LIBS}
2020
)
21-
set_target_properties(${PROJECT_NAME}Tests PROPERTIES CXX_STANDARD 17)
21+
set_target_properties(${PROJECT_NAME}Tests PROPERTIES CXX_STANDARD 11)
2222
# requires std::optional<>
2323

2424
# enable compiler warnings

0 commit comments

Comments
 (0)