KASKADE 7 development version
qp.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2017-2020 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef QP_HH
14#define QP_HH
15
16#include <memory>
17#include <tuple>
18
19#include "dune/istl/bvector.hh"
20
23
24namespace Kaskade
25{
60
64 enum class QPStructure { DENSE, SPARSE };
65
66 //-----------------------------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------------------------
68
77 template <class MatrixA, class MatrixB, class VectorX, class VectorB>
78 std::array<typename ScalarTraits<typename MatrixA::field_type>::Real,4>
79 checkKKT(MatrixA const& A, MatrixB const& B,VectorX const& c, VectorB const& b,
80 VectorX const& x, VectorB const& lambda);
81
82
83 //-----------------------------------------------------------------------------------------------
84 //-----------------------------------------------------------------------------------------------
85
105 template <class Real, class Implementation>
107 {
108 public:
111
113 {}
114
132 std::tuple<Vector,int> solve(Vector const& c, Vector const& b, double tol) const;
133
152 std::tuple<Vector,int> solve(Vector const& x, Vector const& c, Vector const& b, double tol) const;
153
161 void gradientStep(Vector const& c, Vector const& b, Vector& x) const;
162
169 Implementation& setMinSteps(int count);
170
177 Implementation& setMaxSteps(int count);
178
179 protected:
185 : dimension(dim)
186 , minSteps(0)
187 , maxSteps(200)
188 {}
189
200 Vector solveSubmatrix(std::vector<int> const& idx, Vector const& b) const;
201
208 virtual void updateWithColumn(Real a, int i, Vector& s) const;
209
210 private:
211 int dimension; // size of primal variables (i.e. length of x and size of A)
212 int minSteps; // minimal number of steps to perform when solving
213 int maxSteps; // upper bound on iteration count
214
215 bool getProjectedGradient(Vector const& x, Vector const& c, Vector const& b, Vector& g, Vector& s) const;
216 void getProjectedNewton(Vector const& x, Vector const& c, Vector const& b, Vector& g, Vector& s) const;
217
226 bool projectedLineSearch(Vector& x, Vector const& b, Vector& g, Vector& s,
227 Vector const* c=nullptr
228 ) const;
229 void checkNaN(Vector const& v) const;
230
231 virtual void printMatrix(std::ostream& out) const = 0;
232
233 };
234
235 //-----------------------------------------------------------------------------------------------
236 //-----------------------------------------------------------------------------------------------
237
250 template <class R=double>
251 class QPBoundSolver: public QPBoundSolverBase<R,QPBoundSolver<R>>
252 {
254
255 public:
256 using Real = R;
257 using Vector = typename Base::Vector;
259
271
272 private:
273 Matrix A;
274
275 friend Base;
276 void mv(Vector const& x, Vector& Ax) const { A.mv(x,Ax); }
277 Real frobenius_norm() const { return A.frobenius_norm(); }
278 Vector solveSubmatrix(std::vector<int> const& idx, Vector const& b) const;
279
280 virtual void printMatrix(std::ostream& out) const { out << "A = \n" << A; }
281 virtual void updateWithColumn(Real a, int i, Vector& s) const override;
282 };
283
284 //-----------------------------------------------------------------------------------------------
285 //-----------------------------------------------------------------------------------------------
286
300 template <class R=double>
301 class QPDirectSparse: public QPBoundSolverBase<R,QPDirectSparse<R>>
302 {
304
305 public:
306 using Real = R;
307 using Vector = typename Base::Vector; // Dune::BlockVector<Dune::FieldVector<Real,1>>
309
321
322 private:
323 SparseMatrix A;
324 void mv(Vector const&x, Vector& Ax) const { A.mv(x,Ax); }
325 Real frobenius_norm() const;
326 friend Base;
327 Vector solveSubmatrix(std::vector<int> const& idx, Vector const& b) const;
328
329 virtual void printMatrix(std::ostream& out) const { out << "sparse matrix A in triplet format: \n" << A; }
330 };
331
332 //--------------------------------------------------------------------------------------------------------------
333
355 template <QPStructure sparsity=QPStructure::DENSE, class R=double>
356 class QPSlackSolver: public QPBoundSolverBase<R,QPSlackSolver<sparsity,R>>
357 {
360
361 public:
362 using Real = R;
363 using Vector = typename Base::Vector; // Dune::BlockVector<Dune::FieldVector<Real,1>>
364 using Matrix = std::conditional_t<sparsity==QPStructure::DENSE,
367
379
380 private:
381 Matrix A;
382 Matrix B;
383 Real gamma;
384
385 friend Base;
386 void mv(Vector const& x, Vector& Ax) const;
387 Real frobenius_norm() const;
388 Vector solveSubmatrix(std::vector<int> const& idx, Vector const& b) const;
389
390 virtual void printMatrix(std::ostream& out) const { out << "A = \n" << A << "\nB = \n" << B << "\ngamma = " << gamma << "\n"; }
391 };
392
393
394 //--------------------------------------------------------------------------------------------------------------
395 //--------------------------------------------------------------------------------------------------------------
396
422 template <int d, class Real=double>
424 {
426
427 public:
433
445
446 QPSolver(Self const& qp);
447
448 Self& operator=(Self const& qp);
449
469 std::tuple<VectorX,VectorB,int> solve(VectorX const& c, VectorB const& b, double tol) const;
470
474 MatrixB const& matrixB() const
475 {
476 return B;
477 }
478
484
485 private:
486 MatrixA Ainv;
487 MatrixB B;
488 std::unique_ptr<QPBoundSolver<Real>> dual;
489 };
490
491 //--------------------------------------------------------------------------------------------------------------
492 //--------------------------------------------------------------------------------------------------------------
493
523 template <int d, QPStructure sparsity = QPStructure::DENSE, class Real=double>
525 {
528
529 public:
532 using MatrixA = std::conditional_t<sparsity==QPStructure::DENSE,
535 using MatrixB = std::conditional_t<sparsity==QPStructure::DENSE,
538
546 QPPenalizedSolver(MatrixA const& A, MatrixB const& B);
547
555 QPPenalizedSolver(MatrixA const& A, MatrixB const& B, Real gamma);
556
561
566
573
577 Real getPenalty() const { return gamma; }
578
597 std::tuple<VectorX,VectorB,int> solve(VectorX const& c, VectorB const& b, VectorB const& lambda, double tol) const;
598
599
617 std::tuple<VectorX,VectorB,int> solve(VectorX const& c, VectorB const& b,
618 VectorB lambda, double tol, VectorX const& x) const;
619
620 std::tuple<VectorX,int> solve(VectorX const& c, VectorB const& b, double tol, VectorX const& x) const;
621 std::tuple<VectorX,int> solve(VectorX const& c, VectorB const& b, double tol) const;
622
644
650 static constexpr QPStructure sparse = sparsity;
651
652 private:
653 Real gamma = 1e-3;
654 MatrixA A;
655 MatrixB B;
656
657 int minSteps = 0;
658 int maxSteps = 10000;
659
660 std::vector<int> allCols;
661 };
662
663 // ---------------------------------------------------------------------------------------------
664 // ---------------------------------------------------------------------------------------------
665
697 template <int d, QPStructure sparsity = QPStructure::DENSE, class Real=double>
699 {
702
703 public:
706 using MatrixA = std::conditional_t<sparsity==QPStructure::DENSE,
709 using MatrixB = std::conditional_t<sparsity==QPStructure::DENSE,
712
720 QPALSolver(MatrixA const& A, MatrixB const& B);
721
731
741
748
749 Real getPenalty() const { return qp.getPenalty(); }
750
768 std::tuple<VectorX,VectorB,int> solve(VectorX const& c, VectorB const& b, double tol) const;
769
770
787 std::tuple<VectorX,VectorB,int> solve(VectorX const& c, VectorB const& b, double tol, VectorX x) const;
788
794 static constexpr QPStructure sparse = sparsity;
795
796 private:
797 int minSteps = 0;
798 int maxSteps = 10000;
799
801 };
802
803
804}
805
806#endif
void mv(const X &x, Y &y) const
matrix-vector product
field_type mv(X const &x, Y &y) const
Matrix-vector multiplication with computation of if A is square.
An augmented Lagrangian solver for small instances of a particular class of quadratic programs.
Definition: qp.hh:699
QPALSolver(MatrixA const &A, MatrixB const &B)
Constructs the solver, providing the matrices and .
std::tuple< VectorX, VectorB, int > solve(VectorX const &c, VectorB const &b, double tol) const
Solves the QP approximately for the given right hand side vectors.
QPALSolver< d, sparsity, Real > & setPenalty(Real gamma)
Sets the penalty parameter .
Real getPenalty() const
Definition: qp.hh:749
QPALSolver< d, sparsity, Real > & setMinSteps(int i)
Sets the minimum number of augmented Lagrangian steps to perform.
static constexpr QPStructure sparse
Given info on whether dense or sparse arithmetic is used (i.e. the choice of template parameter used ...
Definition: qp.hh:794
std::tuple< VectorX, VectorB, int > solve(VectorX const &c, VectorB const &b, double tol, VectorX x) const
Solves the QP approximately for the given right hand side vectors.
QPALSolver< d, sparsity, Real > & setMaxSteps(int i)
Sets the maximum number of projected gradient steps to perform.
std::conditional_t< sparsity==QPStructure::DENSE, DynamicMatrix< BEntry >, NumaBCRSMatrix< BEntry > > MatrixB
Definition: qp.hh:711
std::conditional_t< sparsity==QPStructure::DENSE, DynamicMatrix< AEntry >, NumaBCRSMatrix< AEntry > > MatrixA
Definition: qp.hh:708
An iterative solver for small instances of bound constrained quadratic programs.
Definition: qp.hh:107
Vector solveSubmatrix(std::vector< int > const &idx, Vector const &b) const
solves a subsystem .
virtual void updateWithColumn(Real a, int i, Vector &s) const
Performs the update , where is the i-th unit vector.
Dune::BlockVector< Dune::FieldVector< Real, 1 > > Vector
Definition: qp.hh:109
std::tuple< Vector, int > solve(Vector const &c, Vector const &b, double tol) const
Solves the QP for the given right hand side vectors.
Implementation & setMinSteps(int count)
defines the minimal number of steps to perform in solving.
void gradientStep(Vector const &c, Vector const &b, Vector &x) const
Performs a single projected gradient step.
Implementation & setMaxSteps(int count)
defines the maximum allowed number of steps to perform in solving.
virtual ~QPBoundSolverBase()
Definition: qp.hh:112
QPBoundSolverBase(int dim)
Constructor (to be used by derived classes only)
Definition: qp.hh:184
std::tuple< Vector, int > solve(Vector const &x, Vector const &c, Vector const &b, double tol) const
Solves the QP for the given right hand side vectors.
An iterative solver for small instances of bound constrained quadratic programs.
Definition: qp.hh:252
QPBoundSolver(Matrix const &A, QPConvexificationStrategy convex=QPConvexificationStrategy::DONOTHING)
Constructs the solver, providing the matrix .
typename Base::Vector Vector
Definition: qp.hh:257
A solver for sparse, medium-sized instances of bound constrained quadratic programs.
Definition: qp.hh:302
QPDirectSparse(SparseMatrix const &A, QPConvexificationStrategy convex=QPConvexificationStrategy::DONOTHING)
Constructs the solver, providing the matrix .
typename Base::Vector Vector
Definition: qp.hh:307
An iterative solver for small instances of a particular class of quadratic programs.
Definition: qp.hh:525
std::tuple< VectorX, VectorB, int > solve(VectorX const &c, VectorB const &b, VectorB const &lambda, double tol) const
Solves the QP approximately for the given right hand side vectors.
std::tuple< VectorX, int > solve(VectorX const &c, VectorB const &b, double tol, VectorX const &x) const
Real getPenalty() const
Returns the used penalty parameter .
Definition: qp.hh:577
QPPenalizedSolver< d, sparsity, Real > & setMaxSteps(int i)
Sets the maximum number of projected gradient steps to perform.
std::conditional_t< sparsity==QPStructure::DENSE, DynamicMatrix< BEntry >, NumaBCRSMatrix< BEntry > > MatrixB
Definition: qp.hh:537
QPPenalizedSolver< d, sparsity, Real > & setMinSteps(int i)
Sets the minimum number of projected gradient steps to perform.
std::tuple< VectorX, VectorB, int > solve(VectorX const &c, VectorB const &b, VectorB lambda, double tol, VectorX const &x) const
Solves the QP approximately for the given right hand side vectors.
std::conditional_t< sparsity==QPStructure::DENSE, DynamicMatrix< AEntry >, NumaBCRSMatrix< AEntry > > MatrixA
Definition: qp.hh:534
VectorB multiplierEstimate(VectorX const &x, VectorX c) const
Computes a least squares multiplier estimate.
QPPenalizedSolver(MatrixA const &A, MatrixB const &B)
Constructs the solver, providing the matrices and .
QPPenalizedSolver< d, sparsity, Real > & setPenalty(Real gamma)
Sets the penalty parameter .
std::tuple< VectorX, int > solve(VectorX const &c, VectorB const &b, double tol) const
static constexpr QPStructure sparse
Given info on whether dense or sparse arithmetic is used (i.e. the choice of template parameter used ...
Definition: qp.hh:650
QPPenalizedSolver(MatrixA const &A, MatrixB const &B, Real gamma)
Constructs the solver, providing the matrices and .
An iterative solver for particular instances of bound constrained quadratic programs.
Definition: qp.hh:357
std::conditional_t< sparsity==QPStructure::DENSE, DynamicMatrix< Entry >, NumaBCRSMatrix< Entry > > Matrix
Definition: qp.hh:366
typename Base::Vector Vector
Definition: qp.hh:363
QPSlackSolver(Matrix const &A, Matrix const &B, Real gamma, QPConvexificationStrategy convex=QPConvexificationStrategy::DONOTHING)
Constructs the solver, providing the matrix and .
An iterative solver for small instances of a particular class of quadratic programs.
Definition: qp.hh:424
static constexpr QPStructure sparse
Given info on whether dense or sparse arithmetic is used.
Definition: qp.hh:483
Self & operator=(Self const &qp)
QPSolver(MatrixA const &A, MatrixB const &B, QPConvexificationStrategy convex=QPConvexificationStrategy::DONOTHING)
Constructs the solver, providing the matrices and .
QPSolver(Self const &qp)
MatrixB const & matrixB() const
Provides access to the internal copy of .
Definition: qp.hh:474
std::tuple< VectorX, VectorB, int > solve(VectorX const &c, VectorB const &b, double tol) const
Solves the QP for the given right hand side vectors.
int count(Cell const &cell, int codim)
Computes the number of subentities of codimension c of a given entity.
Definition: fixdune.hh:716
std::array< typename ScalarTraits< typename MatrixA::field_type >::Real, 4 > checkKKT(MatrixA const &A, MatrixB const &B, VectorX const &c, VectorB const &b, VectorX const &x, VectorB const &lambda)
Computes the KKT residual for approximate solutions of certain QPs.
QPConvexificationStrategy
Definition: qp.hh:59
QPStructure
A flag that determines whether the QP solver shall work with dense or sparse linear algebra.
Definition: qp.hh:64