ZonoOpt v2.1.0
Loading...
Searching...
No Matches
ADMM.hpp
Go to the documentation of this file.
1#ifndef ZONOOPT_ADMM_HPP_
2#define ZONOOPT_ADMM_HPP_
3
16#include <vector>
17#include <chrono>
18#include <stdexcept>
19#include <iostream>
20#include <sstream>
21#include <memory>
22#include <set>
23#include <cmath>
24#include <random>
25#include <atomic>
26
27#include "Eigen/Dense"
28#include "Eigen/Sparse"
29#include "CholeskyUtilities.hpp"
30#include "Intervals.hpp"
33
34/*
35 Primary reference:
36 Boyd, Stephen, et al.
37 "Distributed optimization and statistical learning via the alternating direction method of multipliers."
38 Foundations and TrendsĀ® in Machine learning 3.1 (2011): 1-122.
39*/
40
41namespace ZonoOpt
42{
49 {
51 Eigen::Vector<zono_float, -1> z;
52
54 Eigen::Vector<zono_float, -1> u;
55 };
56
57 namespace detail
58 {
63 struct ADMM_data : std::enable_shared_from_this<ADMM_data>
64 {
65 Eigen::SparseMatrix<zono_float> P, A, AT;
66 Eigen::SparseMatrix<zono_float, Eigen::RowMajor> A_rm;
67 Eigen::Vector<zono_float, -1> q, b;
68 Eigen::Vector<zono_float, 1> c;
69 LDLT_data ldlt_data_M, ldlt_data_AAT;
70 int n_x, n_cons;
71 zono_float sqrt_n_x;
72 std::shared_ptr<Box> x_box;
73 OptSettings settings;
74
75 // constructor
76 ADMM_data() = default;
77
78 ADMM_data(const Eigen::SparseMatrix<zono_float>& P, const Eigen::Vector<zono_float, -1>& q,
79 const Eigen::SparseMatrix<zono_float>& A, const Eigen::Vector<zono_float, -1>& b,
80 const Eigen::Vector<zono_float, -1>& x_l, const Eigen::Vector<zono_float, -1>& x_u,
81 const zono_float c = 0, const OptSettings& settings = OptSettings())
82 {
83 set(P, q, A, b, x_l, x_u, c, settings);
84 }
85
86 // set method
87 void set(const Eigen::SparseMatrix<zono_float>& P, const Eigen::Vector<zono_float, -1>& q,
88 const Eigen::SparseMatrix<zono_float>& A, const Eigen::Vector<zono_float, -1>& b,
89 const Eigen::Vector<zono_float, -1>& x_l, const Eigen::Vector<zono_float, -1>& x_u,
90 const zono_float c = 0, const OptSettings& settings = OptSettings());
91
92 // clone method
93 ADMM_data* clone() const;
94 };
95
96 // utilities
97 class cycle_buffer
98 {
99 public:
100 cycle_buffer(size_t N, zono_float eps_r);
101
102 // returns false if value already contained in set
103 bool insert(zono_float val);
104
105 // get method
106 const std::vector<zono_float>& get_vals() const;
107
108 private:
109 const size_t N;
110 const zono_float eps_r;
111 std::vector<zono_float> buffer;
112 };
113
118 class ADMM_solver
119 {
120 public:
126 explicit ADMM_solver(const ADMM_data& data);
127
133 explicit ADMM_solver(const std::shared_ptr<ADMM_data>& data);
134
140 ADMM_solver(const ADMM_solver& other);
141
146 virtual ~ADMM_solver() = default;
147
154 virtual void warmstart(const Eigen::Vector<zono_float, -1>& x,
155 const Eigen::Vector<zono_float, -1>& u);
156
161 virtual void factorize();
162
169 OptSolution solve(std::atomic<bool>* stop);
170
171 OptSolution solve();
172
173 protected:
174 // protected fields
175 std::shared_ptr<ADMM_data> data;
176 zono_float eps_prim = static_cast<zono_float>(1e-3), eps_dual = static_cast<zono_float>(1e-3);
177
178 // startup method
179 bool startup(Box& x_box, OptSolution& solution, const std::set<int>& contract_inds = std::set<int>());
180
181 // core solve method
182 virtual void solve_core(const Box& x_box, OptSolution& solution, std::atomic<bool>* stop);
183
184 // warm start
185 Eigen::Vector<zono_float, -1> x0, u0;
186
187 // flags
188 bool is_warmstarted = false;
189
190 // factor problem data
191 void factorize_M() const;
192
193 void factorize_AAT() const;
194
195 // check for infeasibility certificate
196 bool is_infeasibility_certificate(const Eigen::Vector<zono_float, -1>& ek,
197 const Eigen::Vector<zono_float, -1>& xk, const Box& x_box) const;
198
199 bool check_problem_dimensions() const;
200 };
201
206 class ADMM_FP_solver : public ADMM_solver
207 {
208 private:
209 std::mt19937 rand_gen;
210
211 void init_rand_gen();
212
213 public:
219 ADMM_FP_solver(const std::shared_ptr<ADMM_data>& data);
225 ADMM_FP_solver(const ADMM_data& data);
226
232 ADMM_FP_solver(const ADMM_FP_solver& other) = default;
233
234 protected:
235 enum FP_Phase
236 {
237 Phase1,
238 Phase2
239 };
240
241 // solve core method
242 void solve_core(const Box& x_box, OptSolution& solution, std::atomic<bool>* stop) override;
243
244 void ADMM_FP_core(const MI_Box& x_box, OptSolution& solution, std::atomic<bool>* stop, FP_Phase phase);
245 };
246 } // end namespace detail
247} // end namespace ZonoOpt
248
249#endif
Internal utilities for Cholesky factorization using Eigen's LDLT solver.
Intervals and associated classes.
Optimization settings and solution data structures for ZonoOpt library.
Utilities for sparse matrix operations in ZonoOpt library.
#define zono_float
Defines the floating-point type used in ZonoOpt.
Definition ZonoOpt.hpp:45
Definition ZonoOpt.hpp:58
Settings for optimization routines in ZonoOpt library.
Definition SolverDataStructures.hpp:25
Warm start parameters for optimization routines in ZonoOpt library.
Definition ADMM.hpp:49
Eigen::Vector< zono_float, -1 > z
primal variable
Definition ADMM.hpp:51
Eigen::Vector< zono_float, -1 > u
dual variable
Definition ADMM.hpp:54