internal virtual void do_shrinking()
{
int i, j, k;
var working_set = new int[2];
if (select_working_set(working_set) != 0)
return;
i = working_set[0];
j = working_set[1];
double Gm1 = (- y[j])*G[j];
double Gm2 = y[i]*G[i];
// shrink
for (k = 0; k < active_size; k++)
{
if (is_lower_bound(k))
{
if (y[k] == + 1)
{
if (- G[k] >= Gm1)
continue;
}
else if (- G[k] >= Gm2)
continue;
}
else if (is_upper_bound(k))
{
if (y[k] == + 1)
{
if (G[k] >= Gm2)
continue;
}
else if (G[k] >= Gm1)
continue;
}
else
continue;
--active_size;
swap_index(k, active_size);
--k; // look at the newcomer
}
// unshrink, check all variables again before final iterations
if (unshrinked || - (Gm1 + Gm2) > eps*10)
return;
unshrinked = true;
reconstruct_gradient();
for (k = l - 1; k >= active_size; k--)
{
if (is_lower_bound(k))
{
if (y[k] == + 1)
{
if (- G[k] < Gm1)
continue;
}
else if (- G[k] < Gm2)
continue;
}
else if (is_upper_bound(k))
{
if (y[k] == + 1)
{
if (G[k] < Gm2)
continue;
}
else if (G[k] < Gm1)
continue;
}
else
continue;
swap_index(k, active_size);
active_size++;
++k; // look at the newcomer
}
}