ZonoOpt 2.2.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 "Box.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
Box and MI_Box classes.
Internal utilities for Cholesky factorization using Eigen's LDLT solver.
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