13#ifndef QPLINESEARCH_HH
14#define QPLINESEARCH_HH
19#include "dune/istl/bvector.hh"
43 template <
class MatrixA,
class MatrixB,
class VectorX,
class VectorB,
class Real>
45 VectorX
const& c, VectorB
const& b, VectorX
const& dx)
48 if (dx.two_norm2() == 0)
51 if (c.two_norm2() == 0)
64 double alpha = dx*Adx / 2;
76 std::cout <<
"Nonconvex direction encountered in QP linesearch: dx^T A dx = " +std::to_string(alpha) <<
"\n";
77 std::cout <<
"set steplength to 0.\n";
82 Real t = -beta/alpha/2;
99 if (gamma == std::numeric_limits<Real>::infinity())
102 for (
int i=0; i<b.N(); ++i)
111 + std::to_string(t) +
").",
119 std::vector<std::pair<Real,Real>> rEtas;
121 for (
int i=0; i<b.N(); ++i)
122 if (Bdx[i]>=0 && b[i]<=0)
124 alpha += gamma/2 * Bdx[i]*Bdx[i];
125 beta -= gamma/2 * 2*Bdx[i]*b[i];
127 else if (Bdx[i]*b[i]>0)
129 double r = b[i]/Bdx[i];
132 rEtas.push_back(std::make_pair(r,eta));
136 alpha += gamma/2 * eta*eta;
137 beta -= gamma/2 * 2*eta*eta*r;
146 t =
std::max(0.0,-beta / (2*alpha));
154 while (!rEtas.empty())
156 if (t < rEtas.back().first)
161 auto [r,Bdx] = rEtas.back();
166 alpha += gamma/2 * Bdx*Bdx;
167 beta -= gamma/2 * 2*Bdx*Bdx*r;
171 alpha -= gamma/2 * Bdx*Bdx;
172 beta += gamma/2 * 2*Bdx*Bdx*r;
195 template <
class MatrixA,
class MatrixB,
class VectorX,
class VectorB,
class Real>
197 VectorX
const& c, VectorB
const& b, VectorX
const& x, VectorX
const& dx)
216 for (
int i=0; i<b.N(); ++i)
219 B.usmtv(gamma,con,c0);
221 if (c0.two_norm() > 1e3* (c.two_norm()+con.two_norm()) * std::numeric_limits<Real>::epsilon())
223 std::cout <<
"|grad| = " << c0.two_norm() <<
", |c| = " << c.two_norm() <<
", |Bx-b|_+ = " << con.two_norm() <<
"\n";
224 throw LinesearchException(ex.what() + std::string(
"Does not appear to be due to roundoff."),__FILE__,__LINE__);
To be raised if an iterative solver detects the problem to be infeasible (has no valid solution).
To be raised if a linesearch fails.
To be raised if the matrix is not positive definite.
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
Real qpLinesearch(MatrixA const &A, MatrixB const &B, Real gamma, VectorX const &c, VectorB const &b, VectorX const &dx)
Performs linesearch for penalized QPs.
A comparator functor that supports sorting std::pair by their first component.