@@ -1064,6 +1064,21 @@ static int solve_l2r_l1l2_svc(const problem *prob, const parameter *param, doubl
10641064 info (" Objective value = %lf\n " ,v/2 );
10651065 info (" nSV = %d\n " ,nSV);
10661066
1067+ // Reconstruct w from the primal-dual relationship w=sum(\alpha_i y_i x_i)
1068+ // This may reduce the weight density. Some zero weights become non-zeros
1069+ // due to the numerical update w <- w + (alpha[i] - alpha_old) y_i x_i.
1070+ if (param->w_recalc )
1071+ {
1072+ for (i=0 ; i<w_size; i++)
1073+ w[i] = 0 ;
1074+ for (i=0 ; i<l; i++)
1075+ {
1076+ feature_node * const xi = prob->x [i];
1077+ if (alpha[i] > 0 )
1078+ sparse_operator::axpy (y[i]*alpha[i], xi, w);
1079+ }
1080+ }
1081+
10671082 delete [] QD;
10681083 delete [] alpha;
10691084 delete [] y;
@@ -2194,11 +2209,14 @@ static int partition(feature_node *nodes, int low, int high)
21942209 return index;
21952210}
21962211
2197- // rearrange nodes so that nodes[:k] contains nodes with the k smallest values.
2212+ // rearrange nodes so that
2213+ // nodes[i] <= nodes[k] for all i < k
2214+ // nodes[k] <= nodes[j] for all j > k
2215+ // low and high are the bounds of the index range during the rearranging process
21982216static void quick_select_min_k (feature_node *nodes, int low, int high, int k)
21992217{
22002218 int pivot;
2201- if (low == high)
2219+ if (low == high || high < k )
22022220 return ;
22032221 pivot = partition (nodes, low, high);
22042222 if (pivot == k)
@@ -3718,6 +3736,11 @@ const char *check_parameter(const problem *prob, const parameter *param)
37183736 && param->solver_type != L2R_L2LOSS_SVR)
37193737 return " Initial-solution specification supported only for solvers L2R_LR, L2R_L2LOSS_SVC, and L2R_L2LOSS_SVR" ;
37203738
3739+ if (param->w_recalc == true
3740+ && param->solver_type != L2R_L2LOSS_SVC_DUAL
3741+ && param->solver_type != L2R_L1LOSS_SVC_DUAL)
3742+ return " Recalculating w in the end is only for dual solvers for L2-regularized L1/L2-loss SVM" ;
3743+
37213744 return NULL ;
37223745}
37233746
0 commit comments