milk/supervised/_svm.cpp
// return true if already optimal, return false otherwise
return true if already optimal, return false otherwise
return true if already optimal return false otherwise
bool LIBSVM_Solver::select_working_set(int &out_i, int &out_j) {
	double Gmax = -INF;
	double Gmax2 = -INF;
	int Gmax_idx = -1;
	int Gmin_idx = -1;
	double obj_diff_min = INF;
	for(int t=0;t<active_size;t++) {
		if( (Y[t] == +1 && !is_upper_bound(t)) ||
            (Y[t] == -1 && !is_lower_bound(t)))	{
            if (-Y[t]*G[t] >= Gmax) {
                Gmax = -Y[t]*G[t];
                Gmax_idx = t;
            }
        }
    }
    if (Gmax_idx == -1) return true;
	const int i = Gmax_idx;
	const double* Q_i = cache_.get_kline(active_set[i], N);
    const double* QDiag = cache_.get_diag();
	for(int j=0;j<active_size;++j) {
        if ((Y[j] == +1 && !is_lower_bound(j)) ||
            (Y[j] == -1 && !is_upper_bound(j))) {
                const double YGj = Y[j]*G[j];
                const double grad_diff = Gmax+YGj;
                if (YGj >= Gmax2) Gmax2 = YGj;
                if (grad_diff > 0) {
                    const double quad_coef = Q_i[active_set[i]] + QDiag[active_set[j]] - 2*Y[j]*Y[i]*Q_i[active_set[j]];
                    const double obj_diff_factor = (quad_coef > 0) ? quad_coef : tau;
                    const double obj_diff = -(grad_diff*grad_diff)/obj_diff_factor;
                    if (obj_diff <= obj_diff_min) {
                        Gmin_idx = j;
                        obj_diff_min = obj_diff;
                    }
                }
        }
	}
    if (Gmin_idx == -1) return true;
	if(Gmax+Gmax2 < eps) return true;
	out_i = Gmax_idx;
	out_j = Gmin_idx;
	return false;
}
bool LIBSVM_Solver :: select_working_set ( int & out_i , int & out_j ) { double Gmax = - INF ; double Gmax2 = - INF ; int Gmax_idx = -1 ; int Gmin_idx = -1 ; double obj_diff_min = INF ; for ( int t = 0 ; t < active_size ; t ++ ) { if ( ( Y [ t ] == +1 && ! is_upper_bound ( t ) ) || ( Y [ t ] == -1 && ! is_lower_bound ( t ) ) ) { if ( - Y [ t ] * G [ t ] >= Gmax ) { Gmax = - Y [ t ] * G [ t ] ; Gmax_idx = t ; } } } if ( Gmax_idx == -1 ) return true ; const int i = Gmax_idx ; const double * Q_i = cache_ . get_kline ( active_set [ i ] , N ) ; const double * QDiag = cache_ . get_diag ( ) ; for ( int j = 0 ; j < active_size ; ++ j ) { if ( ( Y [ j ] == +1 && ! is_lower_bound ( j ) ) || ( Y [ j ] == -1 && ! is_upper_bound ( j ) ) ) { const double YGj = Y [ j ] * G [ j ] ; const double grad_diff = Gmax + YGj ; if ( YGj >= Gmax2 ) Gmax2 = YGj ; if ( grad_diff > 0 ) { const double quad_coef = Q_i [ active_set [ i ] ] + QDiag [ active_set [ j ] ] - 2 * Y [ j ] * Y [ i ] * Q_i [ active_set [ j ] ] ; const double obj_diff_factor = ( quad_coef > 0 ) ? quad_coef : tau ; const double obj_diff = - ( grad_diff * grad_diff ) / obj_diff_factor ; if ( obj_diff <= obj_diff_min ) { Gmin_idx = j ; obj_diff_min = obj_diff ; } } } } if ( Gmin_idx == -1 ) return true ; if ( Gmax + Gmax2 < eps ) return true ; out_i = Gmax_idx ; out_j = Gmin_idx ; return false ; }
return true if already optimal, return false otherwise
return true if already optimal return false otherwise
// return i,j such that // i: maximizes -y_i * grad(f)_i, i in I_up(\alpha) // j: minimizes the decrease of obj value //    (if quadratic coefficeint <= 0, replace it with tau) //    -y_j*grad(f)_j < -y_i*grad(f)_i, j in I_low(\alpha) //print_status();