168 template<
class Problem>
169 double operator()(Problem& problem, std::size_t& i, std::size_t& j)
171 if (smallProblem || useLibSVM || isInCorner(problem))
174 if(!smallProblem &&
sqr(problem.active()) < problem.quadratic().getMaxCacheSize())
177 double value = libSVMSelection(problem,i, j);
183 MGStep besti = selectMGVariable(problem,last_i);
184 if(besti.violation == 0.0)
186 MGStep bestj = selectMGVariable(problem,last_j);
188 if(bestj.gain > besti.gain){
195 if (problem.gradient(i) < problem.gradient(j))
199 return besti.violation;
204 smallProblem =
false;
208 template<
class Problem>
209 bool isInCorner(Problem
const& problem)
const{
210 double Li = problem.boxMin(last_i);
211 double Ui = problem.boxMax(last_i);
212 double Lj = problem.boxMin(last_j);
213 double Uj = problem.boxMax(last_j);
214 double eps_i = 1e-8 * (Ui - Li);
215 double eps_j = 1e-8 * (Uj - Lj);
217 if ((problem.alpha(last_i) <= Li + eps_i || problem.alpha(last_i) >= Ui - eps_i)
218 && ((problem.alpha(last_j) <= Lj + eps_j || problem.alpha(last_j) >= Uj - eps_j)))
229 template<
class Problem>
230 MGStep selectMGVariable(Problem& problem,std::size_t i)
const{
233 std::size_t bestIndex = 0;
236 double largestUp = -1e100;
237 double smallestDown = 1e100;
240 typename Problem::QpFloatType* q = problem.quadratic().row(i, 0, problem.active());
241 double ab = problem.alpha(i);
242 double db = problem.diagonal(i);
243 double Lb = problem.boxMin(i);
244 double Ub = problem.boxMax(i);
245 double gb = problem.gradient(i);
246 for (std::size_t a = 0; a < problem.active(); a++)
248 double ga = problem.gradient(a);
250 if (!problem.isUpperBound(a))
251 largestUp = std::max(largestUp,ga);
252 if (!problem.isLowerBound(a))
253 smallestDown = std::min(smallestDown,ga);
255 if (a == i)
continue;
257 double denominator = (problem.diagonal(a) + db - 2.0 * q[a]);
258 double mu_max = (ga - gb) / denominator;
265 double aa = problem.alpha(a);
266 double La = problem.boxMin(a);
267 double Ua = problem.boxMax(a);
268 double mu_star = mu_max;
269 if (aa + mu_star < La) mu_star = La - aa;
270 else if (mu_star + aa > Ua) mu_star = Ua - aa;
271 if (ab - mu_star < Lb) mu_star = ab - Lb;
272 else if (ab - mu_star > Ub) mu_star = ab - Ub;
274 double gain = mu_star * (2.0 * mu_max - mu_star) * denominator;
284 step.violation= largestUp-smallestDown;
285 step.index = bestIndex;