#else
static void info(const char *fmt,...) {}
#endif
+class sparse_operator
+{
+public:
+ static double nrm2_sq(const feature_node *x)
+ {
+ double ret = 0;
+ while(x->index != -1)
+ {
+ ret += x->value*x->value;
+ x++;
+ }
+ return (ret);
+ }
+
+ static double dot(const double *s, const feature_node *x)
+ {
+ double ret = 0;
+ while(x->index != -1)
+ {
+ ret += s[x->index-1]*x->value;
+ x++;
+ }
+ return (ret);
+ }
+
+ static void axpy(const double a, const feature_node *x, double *y)
+ {
+ while(x->index != -1)
+ {
+ y[x->index-1] += a*x->value;
+ x++;
+ }
+ }
+};
class l2r_lr_fun: public function
{
int l=prob->l;
int w_size=get_nr_variable();
double *wa = new double[l];
+ feature_node **x=prob->x;
- Xv(s, wa);
+ for(i=0;i<w_size;i++)
+ Hs[i] = 0;
for(i=0;i<l;i++)
+ {
+ feature_node * const xi=x[i];
+ wa[i] = sparse_operator::dot(s, xi);
+
wa[i] = C[i]*D[i]*wa[i];
- XTv(wa, Hs);
+ sparse_operator::axpy(wa[i], xi, Hs);
+ }
for(i=0;i<w_size;i++)
Hs[i] = s[i] + Hs[i];
delete[] wa;
feature_node **x=prob->x;
for(i=0;i<l;i++)
- {
- feature_node *s=x[i];
- Xv[i]=0;
- while(s->index!=-1)
- {
- Xv[i]+=v[s->index-1]*s->value;
- s++;
- }
- }
+ Xv[i]=sparse_operator::dot(v, x[i]);
}
void l2r_lr_fun::XTv(double *v, double *XTv)
for(i=0;i<w_size;i++)
XTv[i]=0;
for(i=0;i<l;i++)
- {
- feature_node *s=x[i];
- while(s->index!=-1)
- {
- XTv[s->index-1]+=v[i]*s->value;
- s++;
- }
- }
+ sparse_operator::axpy(v[i], x[i], XTv);
}
class l2r_l2_svc_fun: public function
protected:
void Xv(double *v, double *Xv);
- void subXv(double *v, double *Xv);
void subXTv(double *v, double *XTv);
double *C;
int i;
int w_size=get_nr_variable();
double *wa = new double[sizeI];
+ feature_node **x=prob->x;
- subXv(s, wa);
+ for(i=0;i<w_size;i++)
+ Hs[i]=0;
for(i=0;i<sizeI;i++)
+ {
+ feature_node * const xi=x[I[i]];
+ wa[i] = sparse_operator::dot(s, xi);
+
wa[i] = C[I[i]]*wa[i];
- subXTv(wa, Hs);
+ sparse_operator::axpy(wa[i], xi, Hs);
+ }
for(i=0;i<w_size;i++)
Hs[i] = s[i] + 2*Hs[i];
delete[] wa;
feature_node **x=prob->x;
for(i=0;i<l;i++)
- {
- feature_node *s=x[i];
- Xv[i]=0;
- while(s->index!=-1)
- {
- Xv[i]+=v[s->index-1]*s->value;
- s++;
- }
- }
-}
-
-void l2r_l2_svc_fun::subXv(double *v, double *Xv)
-{
- int i;
- feature_node **x=prob->x;
-
- for(i=0;i<sizeI;i++)
- {
- feature_node *s=x[I[i]];
- Xv[i]=0;
- while(s->index!=-1)
- {
- Xv[i]+=v[s->index-1]*s->value;
- s++;
- }
- }
+ Xv[i]=sparse_operator::dot(v, x[i]);
}
void l2r_l2_svc_fun::subXTv(double *v, double *XTv)
for(i=0;i<w_size;i++)
XTv[i]=0;
for(i=0;i<sizeI;i++)
- {
- feature_node *s=x[I[i]];
- while(s->index!=-1)
- {
- XTv[s->index-1]+=v[i]*s->value;
- s++;
- }
- }
+ sparse_operator::axpy(v[i], x[I[i]], XTv);
}
class l2r_l2_svr_fun: public l2r_l2_svc_fun
{
QD[i] = diag[GETI(i)];
- feature_node *xi = prob->x[i];
- while (xi->index != -1)
- {
- double val = xi->value;
- QD[i] += val*val;
- w[xi->index-1] += y[i]*alpha[i]*val;
- xi++;
- }
+ feature_node * const xi = prob->x[i];
+ QD[i] += sparse_operator::nrm2_sq(xi);
+ sparse_operator::axpy(y[i]*alpha[i], xi, w);
+
index[i] = i;
}
for (s=0; s<active_size; s++)
{
i = index[s];
- G = 0;
- schar yi = y[i];
+ const schar yi = y[i];
+ feature_node * const xi = prob->x[i];
- feature_node *xi = prob->x[i];
- while(xi->index!= -1)
- {
- G += w[xi->index-1]*(xi->value);
- xi++;
- }
- G = G*yi-1;
+ G = yi*sparse_operator::dot(w, xi)-1;
C = upper_bound[GETI(i)];
G += alpha[i]*diag[GETI(i)];
double alpha_old = alpha[i];
alpha[i] = min(max(alpha[i] - G/QD[i], 0.0), C);
d = (alpha[i] - alpha_old)*yi;
- xi = prob->x[i];
- while (xi->index != -1)
- {
- w[xi->index-1] += d*xi->value;
- xi++;
- }
+ sparse_operator::axpy(d, xi, w);
}
}
w[i] = 0;
for(i=0; i<l; i++)
{
- QD[i] = 0;
- feature_node *xi = prob->x[i];
- while(xi->index != -1)
- {
- double val = xi->value;
- QD[i] += val*val;
- w[xi->index-1] += beta[i]*val;
- xi++;
- }
+ feature_node * const xi = prob->x[i];
+ QD[i] = sparse_operator::nrm2_sq(xi);
+ sparse_operator::axpy(beta[i], xi, w);
index[i] = i;
}
G = -y[i] + lambda[GETI(i)]*beta[i];
H = QD[i] + lambda[GETI(i)];
- feature_node *xi = prob->x[i];
- while(xi->index != -1)
- {
- int ind = xi->index-1;
- double val = xi->value;
- G += val*w[ind];
- xi++;
- }
+ feature_node * const xi = prob->x[i];
+ G += sparse_operator::dot(w, xi);
double Gp = G+p;
double Gn = G-p;
d = beta[i]-beta_old;
if(d != 0)
- {
- xi = prob->x[i];
- while(xi->index != -1)
- {
- w[xi->index-1] += d*xi->value;
- xi++;
- }
- }
+ sparse_operator::axpy(d, xi, w);
}
if(iter == 0)
w[i] = 0;
for(i=0; i<l; i++)
{
- xTx[i] = 0;
- feature_node *xi = prob->x[i];
- while (xi->index != -1)
- {
- double val = xi->value;
- xTx[i] += val*val;
- w[xi->index-1] += y[i]*alpha[2*i]*val;
- xi++;
- }
+ feature_node * const xi = prob->x[i];
+ xTx[i] = sparse_operator::nrm2_sq(xi);
+ sparse_operator::axpy(y[i]*alpha[2*i], xi, w);
index[i] = i;
}
for (s=0; s<l; s++)
{
i = index[s];
- schar yi = y[i];
+ const schar yi = y[i];
double C = upper_bound[GETI(i)];
double ywTx = 0, xisq = xTx[i];
- feature_node *xi = prob->x[i];
- while (xi->index != -1)
- {
- ywTx += w[xi->index-1]*xi->value;
- xi++;
- }
- ywTx *= y[i];
+ feature_node * const xi = prob->x[i];
+ ywTx = yi*sparse_operator::dot(w, xi);
double a = xisq, b = ywTx;
// Decide to minimize g_1(z) or g_2(z)
{
alpha[ind1] = z;
alpha[ind2] = C-z;
- xi = prob->x[i];
- while (xi->index != -1)
- {
- w[xi->index-1] += sign*(z-alpha_old)*yi*xi->value;
- xi++;
- }
+ sparse_operator::axpy(sign*(z-alpha_old)*yi, xi, w);
}
}
if(appxcond <= 0)
{
x = prob_col->x[j];
- while(x->index != -1)
- {
- b[x->index-1] += d_diff*x->value;
- x++;
- }
+ sparse_operator::axpy(d_diff, x, b);
break;
}
{
if(w[i]==0) continue;
x = prob_col->x[i];
- while(x->index != -1)
- {
- b[x->index-1] -= w[i]*x->value;
- x++;
- }
+ sparse_operator::axpy(-w[i], x, b);
}
}
}
wpd[j] += z;
x = prob_col->x[j];
- while(x->index != -1)
- {
- int ind = x->index-1;
- xTd[ind] += x->value*z;
- x++;
- }
+ sparse_operator::axpy(z, x, xTd);
}
iter++;
{
if(w[i]==0) continue;
x = prob_col->x[i];
- while(x->index != -1)
- {
- exp_wTx[x->index-1] += w[i]*x->value;
- x++;
- }
+ sparse_operator::axpy(w[i], x, exp_wTx);
}
for(int i=0; i<l; i++)