37 #ifndef SHARK_ALGORITHMS_QP_QPMCSIMPLEXDECOMP_H 38 #define SHARK_ALGORITHMS_QP_QPMCSIMPLEXDECOMP_H 42 #include <shark/Algorithms/QP/Impl/AnalyticProblems.h> 49 template <
class Matrix>
59 template<
class Problem>
60 double operator()(Problem& problem, std::size_t& i, std::size_t& j){
62 return problem.selectWorkingSet(i,j);
78 RealMatrix
const& linearMat,
97 SHARK_RUNTIME_CHECK(kernel.size() == linearMat.size1(),
"size of kernel matrix and linear factor to not agree");
104 unsigned int y = target.
element(i);
113 for (std::size_t p=0; p<
m_cardP; p++, v++)
118 double Q =
m_M(
m_classes * (y * m_cardP + p) + y, p) * k;
143 return solutionMatrix;
152 return solutionGradientMatrix;
198 std::size_t r =
m_cardP * y + p;
229 std::size_t rv =
m_cardP*yv+pv;
230 std::size_t rw =
m_cardP*yw+pw;
269 for(std::size_t p = 0; p !=
m_cardP; ++p){
274 for(std::size_t p = 0; p !=
m_cardP; ++p){
301 std::pair<std::pair<double,std::size_t>,std::pair<double,std::size_t> > pair =
getSimplexMVP(ex);
302 double up = pair.first.first;
303 double down = pair.second.first;
307 if(down > 0 && ex.
varsum ==
m_C && up-down > 0){
309 for(
int p = pc-1; p >= 0; --p){
313 if(a == 0 && g-down < 0){
316 else if (a ==
m_C && up-g < 0){
320 for(
int q = (
int)ex.
active; q >= 0; --q){
329 else if(ex.
varsum == 0 && up < 0){
331 for(
int p = pc-1; p >= 0; --p){
357 if (mu == 0.0)
continue;
362 std::size_t r =
m_cardP * yv + pv;
372 for (std::size_t b=0; b<row.
size; b++)
380 double upd = mu * def * k;
383 std::size_t f = ex.
avar[b];
412 double maxGradient = 0;
413 double maxSimplexGradient = 0;
414 std::size_t maxSimplexExample = 0;
423 std::pair<std::pair<double,std::size_t>,std::pair<double,std::size_t> > pair =
getSimplexMVP(ex);
424 double up = pair.first.first;
425 double down = pair.second.first;
427 if(!canGrow && up - down > maxSimplexGradient){
428 maxSimplexGradient = up-down;
429 maxSimplexExample = e;
431 if (canGrow && up > maxGradient) {
433 i = pair.first.second;
435 if (-down > maxGradient) {
437 i = pair.second.second;
443 std::pair<std::pair<std::size_t,std::size_t> ,
double > boxPair =
maxGainBox(i);
444 double bestGain = boxPair.second;
445 std::pair<std::size_t, std::size_t> best = boxPair.first;
449 if(simplexPairi.second > bestGain){
450 best = simplexPairi.first;
451 bestGain = simplexPairi.second;
454 if(maxSimplexGradient > 0){
455 std::pair<std::pair<std::size_t,std::size_t> ,
double > simplexPairBest =
maxGainSimplex(maxSimplexExample);
456 if(simplexPairBest.second > bestGain){
457 best = simplexPairBest.first;
458 bestGain = simplexPairBest.second;
464 return std::max(maxGradient,maxSimplexGradient);
473 std::pair<std::pair<double,std::size_t>,std::pair<double,std::size_t> > pair =
getSimplexMVP(ex);
474 double up = pair.first.first;
475 double down = pair.second.first;
479 ret = std::max(-down, ret);
482 ret = std::max(up, ret);
485 ret = std::max(up-down, ret);
529 std::pair<std::pair<std::size_t,std::size_t>,
double>
maxGainBox(std::size_t i)
const{
537 return std::make_pair(std::make_pair(i,i),0.0);
542 std::size_t bestj = i;
543 double bestGain = gi * gi / Qii;
551 unsigned int ya = exa.
y;
557 for (std::size_t p=0, b=0; p <
m_cardP; p++)
559 std::size_t j = exa.
var[p];
563 double Qij = def * k[a];
574 double gain = detail::maximumGainQuadratic2D(Qii, Qjj, Qij, gi,gj);
575 if( bestGain < gain){
581 return std::make_pair(std::make_pair(i,bestj),bestGain);
589 std::pair<std::pair<std::size_t,std::size_t>,
double>
maxGainSimplex(std::size_t e)
const{
591 std::size_t pc = ex.
active;
592 unsigned int y = ex.
y;
596 double bestGain = -1e100;
597 std::size_t besti = 0;
598 std::size_t bestj = 0;
611 for(std::size_t p1 = 0; p1 != pc; ++p1){
612 std::size_t i = ex.
avar[p1];
618 if((gi < 0 &&
m_alpha(i) > 0.0) || (gi > 0 && canGrow)){
619 double gain = gi * gi / Qii;
637 for(std::size_t p2 = 0, b=0; p2 !=
m_cardP; ++p2){
638 std::size_t j = ex.
var[p2];
644 double Qij = def * Qee;
658 if(!canGrow && gi > 0 && gj > 0){
662 if(aj > 0 && gi-gj > 0){
663 gainUp = detail::maximumGainQuadratic2DOnLine(Qii, Qjj, Qij, gi,gj);
666 if (ai > 0 &&gj-gi > 0){
667 gainDown = detail::maximumGainQuadratic2DOnLine(Qjj, Qii, Qij, gj,gi);
669 gain = std::max(gainUp,gainDown);
673 else if(!(gi <= 0 && ai == 0) && !(gj<= 0 && aj == 0)){
674 gain = detail::maximumGainQuadratic2D(Qii, Qjj, Qij, gi,gj);
687 return std::make_pair(std::make_pair(besti,bestj),bestGain);
692 std::pair<double,std::size_t>,
693 std::pair<double,std::size_t>
695 std::size_t pc = ex.
active;
698 std::size_t maxUp = ex.
avar[0];
699 std::size_t minDown = ex.
avar[0];
700 for (std::size_t p = 0; p != pc; p++)
702 std::size_t v = ex.
avar[p];
710 if (a > 0.0 && g < down){
715 return std::make_pair(std::make_pair(up,maxUp),std::make_pair(down,minDown));
719 double& varsum =
m_examples[exampleId].varsum;
721 if(varsum > 1.e-12 &&
m_C-varsum > 1.e-12*
m_C)
726 for(std::size_t p = 0; p !=
m_cardP; ++p){
727 std::size_t varIndex =
m_examples[exampleId].var[p];
733 if(
m_C-varsum < 1.e-14*
m_C)
745 for (std::size_t b=0; b<row.
size; b++){
750 double upd = mu* def * k;
751 for (std::size_t b=0; b<ex.
active; b++)
765 std::size_t ih = exv->
active - 1;
766 std::size_t
h = exv->
avar[ih];
811 for (std::size_t v = 0; v <
m_cardP; v++)
885 template<
class Matrix>
898 std::size_t classes = bias.size();
899 std::size_t numExamples = m_problem->getNumExamples();
900 std::size_t
cardP = m_problem->cardP();
901 RealVector stepsize(classes, 0.01);
902 RealVector prev(classes,0);
903 RealVector step(classes);
906 unsigned long long iterations = 0;
911 solver.
solve(stop, &propInner);
917 RealMatrix dualGradient = m_problem->solutionGradient();
919 RealVector grad(classes,0);
921 for (std::size_t i=0; i<numExamples; i++){
922 std::size_t largestP =
cardP;
923 double largest_value = 0.0;
924 for (std::size_t p=0; p<
cardP; p++)
926 if (dualGradient(i,p) > largest_value)
928 largest_value = dualGradient(i,p);
932 if (largestP < cardP)
934 unsigned int y = m_problem->label(i);
936 for (std::size_t b=0; b != row.
size; b++)
944 grad -= sum(grad) / classes;
948 for (std::size_t c=0; c<classes; c++)
952 step(c) = -stepsize(c);
954 step(c) = stepsize(c);
956 double gg = prev(c) * grad(c);
967 step -= sum(step) / classes;
972 performBiasUpdate(step,nu);
974 if (max(stepsize) < 0.01 * stop.
minAccuracy)
break;
982 prop->accuracy = m_problem->checkKKT();
983 prop->value = m_problem->functionValue();
984 prop->iterations = iterations;
985 prop->seconds = finish_time - start_time;
989 void performBiasUpdate(
992 std::size_t numExamples = m_problem->getNumExamples();
993 std::size_t
cardP = m_problem->cardP();
994 RealMatrix deltaLinear(numExamples,cardP,0.0);
995 for (std::size_t i=0; i<numExamples; i++){
996 for (std::size_t p=0; p<
cardP; p++){
997 unsigned int y = m_problem->label(i);
999 for (std::size_t b=0; b<row.
size; b++)
1005 m_problem->addDeltaLinear(deltaLinear);