32 #ifndef SHARK_ALGORITHMS_QP_BOXCONSTRAINEDPROBLEMS_H 33 #define SHARK_ALGORITHMS_QP_BOXCONSTRAINEDPROBLEMS_H 36 #include <shark/Algorithms/QP/Impl/AnalyticProblems.h> 45 template<
class Problem>
46 double operator()(Problem& problem, std::size_t& i, std::size_t& j){
49 double largestGradient = 0;
50 double secondLargestGradient = 0;
52 for (std::size_t a = 0; a < problem.active(); a++){
53 double g = problem.gradient(a);
54 if (!problem.isUpperBound(a) && g > secondLargestGradient){
55 secondLargestGradient = g;
58 if (!problem.isLowerBound(a) && -g > secondLargestGradient){
59 secondLargestGradient = -g;
62 if(secondLargestGradient > largestGradient){
63 std::swap(secondLargestGradient,largestGradient);
67 if(secondLargestGradient == 0)
69 return largestGradient;
79 template<
class Problem>
80 double operator()(Problem& problem, std::size_t& i, std::size_t& j){
82 double value = criterion(problem, i,j);
92 template<
class Problem>
93 double operator()(Problem& problem, std::size_t& i, std::size_t& j){
96 double maxGrad = firstOrder(problem,i,j);
100 double gi = problem.gradient(i);
101 typename Problem::QpFloatType* q = problem.quadratic().row(i, 0, problem.active());
102 double Qii = problem.diagonal(i);
105 double maxGain = 0.0;
106 for (std::size_t a=0; a<problem.active(); a++)
108 if (a == i)
continue;
109 double ga = problem.gradient(a);
111 (!problem.isLowerBound(a) && ga < 0.0)
112 || (!problem.isUpperBound(a) && ga > 0.0)
115 double Qaa = problem.diagonal(a);
116 double gain = detail::maximumGainQuadratic2D(Qii,Qaa,Qia,gi,ga);
137 template<
class SVMProblem>
147 , m_gradient(problem.linear)
148 , m_active (problem.dimensions())
149 , m_alphaStatus(problem.dimensions(),
AlphaFree){
151 for (std::size_t i=0; i != dimensions(); i++){
154 QpFloatType* q = quadratic().row(i, 0, dimensions());
155 for (std::size_t a=0; a < dimensions(); a++)
156 m_gradient(a) -= q[a] * v;
158 updateAlphaStatus(i);
162 return m_problem.dimensions();
182 return isUpperBound(i) && isLowerBound(i);
187 return m_problem.quadratic;
191 return m_problem.linear(i);
195 return m_problem.alpha(i);
199 return m_problem.diagonal(i);
203 return m_gradient(i);
207 return m_problem.permutation[i];
211 RealVector alpha(dimensions());
212 for (std::size_t i=0; i<dimensions(); i++)
213 alpha(m_problem.permutation[i]) = m_problem.alpha(i);
223 QpFloatType* q = quadratic().row(i, 0, active());
227 double mu = -alpha(i);
228 detail::solveQuadraticEdge(m_problem.alpha(i),gradient(i),diagonal(i),boxMin(i),boxMax(i));
232 for (std::size_t a = 0; a < active(); a++)
233 m_gradient(a) -= mu * q[a];
235 updateAlphaStatus(i);
239 double Li = boxMin(i);
240 double Ui = boxMax(i);
241 double Lj = boxMin(j);
242 double Uj = boxMax(j);
245 QpFloatType* qi = quadratic().row(i, 0, active());
246 QpFloatType* qj = quadratic().row(j, 0, active());
250 double mui = -alpha(i);
251 double muj = -alpha(j);
252 detail::solveQuadratic2DBox(m_problem.alpha(i), m_problem.alpha(j),
253 m_gradient(i), m_gradient(j),
254 diagonal(i), qi[j], diagonal(j),
261 for (std::size_t a = 0; a < active(); a++)
262 m_gradient(a) -= mui * qi[a] + muj * qj[a];
264 updateAlphaStatus(i);
265 updateAlphaStatus(j);
270 return 0.5*inner_prod(m_gradient+m_problem.linear,m_problem.alpha);
284 std::size_t n = dimensions();
287 for (std::size_t i=0; i<n; i++)
289 std::size_t j = permutation(i);
290 SHARK_ASSERT(alpha(j) >= boxMin(j) && alpha(j) <= boxMax(j));
291 m_problem.alpha(i) = alpha(j);
292 m_gradient(i) = gradient(j);
293 updateAlphaStatus(i);
305 std::size_t n = dimensions();
307 RealVector gradient = m_problem.linear;
308 blas::vector<QpFloatType> q(n);
309 for (std::size_t i=0; i<n; i++)
312 if (a == 0.0)
continue;
313 m_problem.quadratic.row(i, 0, n, q.storage());
314 noalias(gradient) -= a * q;
316 setInitialSolution(alpha, gradient);
322 double alphai = alpha(i);
323 m_problem.alpha(i) = 0;
325 QpFloatType* qi = quadratic().row(i, 0, active());
326 for (std::size_t a = 0; a < active(); a++)
327 m_gradient(a) += alphai * qi[a];
333 updateAlphaStatus(i);
343 m_problem.flipCoordinates(i, j);
344 std::swap( m_gradient[i], m_gradient[j]);
345 std::swap( m_alphaStatus[i], m_alphaStatus[j]);
350 m_gradient(i) -= linear(i);
351 m_gradient(i) += newValue;
352 m_problem.linear(i) = newValue;
356 double maxViolation = 0.0;
357 for(std::size_t i = 0; i != dimensions(); ++i){
358 if(isDeactivated(i))
continue;
359 if(!isUpperBound(i)){
360 maxViolation = std::max(maxViolation, gradient(i));
362 if(!isLowerBound(i)){
363 maxViolation = std::max(maxViolation, -gradient(i));
382 if(m_problem.alpha(i) == boxMax(i))
384 if(m_problem.alpha(i) == boxMin(i))
389 smallestDown = std::min(smallestDown, 0.0);
390 largestUp = std::max(largestUp, 0.0);
392 ( isLowerBound(a) && gradient(a) < smallestDown)
393 || ( isUpperBound(a) && gradient(a) >largestUp)
403 template<
class Problem>