EllAlgo 1.6.14
Loading...
Searching...
No Matches
chebyshev_oracle.hpp
Go to the documentation of this file.
1
6// -*- coding: utf-8 -*-
7#pragma once
8
9#include <cmath> // for sqrt
10#include <cstddef>
11#include <tuple> // for tuple
12#include <utility>
13#include <valarray>
14#include <vector>
15
16#include "../round_robin.hpp"
17
38 public:
39 using Vec = std::valarray<double>;
40 using ArrayType = Vec;
41 using Cut = std::pair<Vec, double>;
42
49 ChebyshevOracle(const std::vector<Vec>& A, const Vec& b)
50 : _A{A}, _b{b}, _norms(Vec(A.size())), _rr{A.size()} {
51 for (std::size_t i = 0; i != A.size(); ++i) {
52 this->_norms[i] = std::sqrt((this->_A[i] * this->_A[i]).sum());
53 }
54 }
55
57 auto operator=(const ChebyshevOracle&) -> ChebyshevOracle& = delete;
60 ~ChebyshevOracle() = default;
61
69 auto assess_optim(const Vec& xc, double& gamma) -> std::tuple<Cut, bool> {
70 const auto n = xc.size() - 1; // dimension of the center x
71 const auto r = xc[n]; // radius
72
73 // Feasibility: aᵢᵀx + ‖aᵢ‖₂ r ≤ bᵢ (round robin)
74 for (std::size_t i = 0; i != this->_norms.size(); ++i) {
75 const auto k = this->_rr.next();
76 double fj = -this->_b[k] + this->_norms[k] * r;
77 for (std::size_t j = 0; j != n; ++j) {
78 fj += this->_A[k][j] * xc[j];
79 }
80 if (fj > 0.0) {
81 auto g = Vec(xc.size());
82 for (std::size_t j = 0; j != n; ++j) {
83 g[j] = this->_A[k][j];
84 }
85 g[n] = this->_norms[k];
86 return {{std::move(g), fj}, false};
87 }
88 }
89
90 // Optimality: maximize r
91 const auto f0 = r;
92 auto g = Vec(xc.size());
93 g[n] = -1.0; // gradient of -(r - gamma)
94 if (gamma - f0 > 0.0) {
95 return {{std::move(g), gamma - f0}, false}; // deep cut toward gamma
96 }
97 gamma = f0; // improved
98 return {{std::move(g), 0.0}, true};
99 }
100
101 private:
102 std::vector<Vec> _A;
103 Vec _b;
104 Vec _norms;
105 RoundRobin _rr;
106};
double sum(const Arr &a)
Sum of all elements.
Definition arr.hpp:260
Oracle for the Chebyshev center of a polyhedron.
Definition chebyshev_oracle.hpp:37
ChebyshevOracle(const ChebyshevOracle &)=delete
auto assess_optim(const Vec &xc, double &gamma) -> std::tuple< Cut, bool >
Assess feasibility and optimality at a candidate point.
Definition chebyshev_oracle.hpp:69
~ChebyshevOracle()=default
ChebyshevOracle(ChebyshevOracle &&)=delete
std::pair< Vec, double > Cut
Definition chebyshev_oracle.hpp:41
auto operator=(ChebyshevOracle &&) -> ChebyshevOracle &=delete
auto operator=(const ChebyshevOracle &) -> ChebyshevOracle &=delete
std::valarray< double > Vec
Definition chebyshev_oracle.hpp:39
ChebyshevOracle(const std::vector< Vec > &A, const Vec &b)
Construct from halfspace data.
Definition chebyshev_oracle.hpp:49
Vec ArrayType
Definition chebyshev_oracle.hpp:40
Round-robin index generator over a half-open range [lo, hi)
Definition round_robin.hpp:18
auto next() -> std::size_t
Advance to the next index and return it.
Definition round_robin.hpp:30
auto invalid_value() -> T
Return an invalid/sentinel value for type T.
Definition cutting_plane.hpp:27