53    template<
class ProblemT>
 
   56    , m_isUnshrinked(false)
 
   58    , m_gradientEdge(problem.linear)
 
 
   62    using Problem::gradient;
 
   63    using Problem::linear;
 
   64    using Problem::active;
 
   65    using Problem::dimensions;
 
   66    using Problem::quadratic;
 
   67    using Problem::isLowerBound;
 
   68    using Problem::isUpperBound;
 
   69    using Problem::boxMin;
 
   70    using Problem::boxMax;
 
   71    using Problem::setInitialSolution;
 
   73    virtual void updateSMO(std::size_t i, std::size_t j){
 
   74        double aiOld = alpha(i);
 
   75        double ajOld = alpha(j);
 
   77        Problem::updateSMO(i,j);
 
   82        updateGradientEdge(i,aiOld,ai);
 
   83        updateGradientEdge(j,ajOld,aj);
 
 
   87        if(!m_shrink) 
return false;
 
   91        getMaxKKTViolations(largestUp,smallestDown,active());
 
   94        if (!m_isUnshrinked  && (largestUp - smallestDown < 10.0 * epsilon))
 
   98            getMaxKKTViolations(largestUp, smallestDown, dimensions());
 
  101        auto& active = this->m_active;
 
  102        for (std::size_t a = active; a > 0; --a){
 
  104            if(Problem::testShrinkVariable(i, largestUp, smallestDown)){
 
  105                Problem::flipCoordinates(i,active-1);
 
  106                std::swap( m_gradientEdge[i], m_gradientEdge[active-1]);
 
 
  115        if (active() == dimensions()) 
return;
 
  116        m_isUnshrinked = 
true;
 
  125        for (std::size_t a = active(); a < dimensions(); a++)
 
  126            this->m_gradient(a) = m_gradientEdge(a);
 
  128        for (std::size_t i = 0; i < active(); i++){
 
  130            if (isUpperBound(i) || isLowerBound(i)) 
continue;
 
  132            QpFloatType* q = quadratic().row(i, 0, dimensions());
 
  133            for (std::size_t a = active(); a < dimensions(); a++) 
 
  134                this->m_gradient(a) -= alpha(i) * q[a];
 
  137        this->m_active = dimensions();
 
 
  141        m_shrink = shrinking;
 
 
  151    void setInitialSolution(RealVector 
const& alpha, RealVector 
const& gradient, RealVector 
const& gradientEdge){
 
  152        Problem::setInitialSolution(alpha,gradient);
 
  153        std::size_t n = dimensions();
 
  155        for (std::size_t i=0; i<n; i++){
 
  156            std::size_t j = this->permutation(i);
 
  157            m_gradientEdge(i) = gradientEdge(j);
 
 
  168        std::size_t n = dimensions();
 
  170        RealVector gradient = this->m_problem.linear;
 
  171        RealVector gradientEdge = this->m_problem.linear;
 
  172        blas::vector<QpFloatType> q(n);
 
  173        std::vector<std::size_t> inverse(n);
 
  174        for (std::size_t i=0; i<n; i++) 
 
  175            inverse[this->permutation(i)] = i;
 
  176        for (std::size_t i=0; i<n; i++)
 
  179            if (a == 0.0) 
continue;
 
  180            this->m_problem.quadratic.row(i, 0, n, q.raw_storage().values);
 
  181            noalias(gradient) -= a * q;
 
  182            std::size_t j = inverse[i];
 
  183            if (a == boxMin(j) || a == boxMax(j)) gradientEdge -= a * q;
 
 
  191        RealVector alpha_old(dimensions);
 
  192        for(std::size_t i = 0; i != dimensions; ++i){
 
  193            updateGradientEdge(i,alpha_old(i), alpha(i));
 
 
  199        Problem::scaleBoxConstraints(factor,variableScalingFactor);
 
  200        if(factor != variableScalingFactor){
 
  201            for(std::size_t i = 0; i != dimensions(); ++i){
 
  202                m_gradientEdge(i) = linear(i);
 
  206            for(std::size_t i = 0; i != dimensions(); ++i){
 
  207                m_gradientEdge(i) -= linear(i);
 
  208                m_gradientEdge(i) *= factor;
 
  209                m_gradientEdge(i) += linear(i);
 
 
  216        m_gradientEdge(i) -= linear(i);
 
  217        m_gradientEdge(i) += newValue;
 
  218        Problem::setLinear(i,newValue);
 
 
  223        Problem::flipCoordinates(i,j);
 
  224        std::swap( m_gradientEdge[i], m_gradientEdge[j]);
 
 
  232    void updateGradientEdge(std::size_t i, 
double oldAlpha, 
double newAlpha){
 
  234        if(!m_shrink || oldAlpha==newAlpha) 
return;
 
  235        bool isInsideOld = oldAlpha > boxMin(i) && oldAlpha < boxMax(i);
 
  236        bool isInsideNew = newAlpha > boxMin(i) && newAlpha < boxMax(i);
 
  239        if((oldAlpha == 0 || isInsideOld) && isInsideNew)
 
  250        QpFloatType* q = quadratic().row(i, 0, dimensions());
 
  251        for(std::size_t a = 0; a != dimensions(); ++a){
 
  252            m_gradientEdge(a) -= diff*q[a];
 
  256    void getMaxKKTViolations(
double& largestUp, 
double& smallestDown, std::size_t maxIndex){
 
  258        smallestDown = 1e100;
 
  259        for (std::size_t a = 0; a < maxIndex; a++){
 
  260            if (!isLowerBound(a))
 
  261                smallestDown = std::min(smallestDown,gradient(a));
 
  262            if (!isUpperBound(a))
 
  263                largestUp = std::max(largestUp,gradient(a));
 
  273    RealVector m_gradientEdge;