16 template <
class T>
static inline T min(
T x,
T y) {
return (x<y)?x:
y; }
19 template <
class T>
static inline T max(
T x,
T y) {
return (x>y)?x:
y; }
21 template <
class T>
static inline void swap(
T&
x,
T&
y) {
T t=
x; x=
y; y=t; }
22 template <
class S,
class T>
static inline void clone(
T*& dst, S* src,
int n)
25 memcpy((
void *)dst,(
void *)src,
sizeof(
T)*n);
27 static inline double powi(
double base,
int times)
29 double tmp = base, ret = 1.0;
31 for (
int t=times; t>0; t/=2 ) {
32 if ( t%2==1 ) ret*=tmp;
39 #define Malloc(type,n) (type *)malloc((n)*sizeof(type))
48 static void info(
const char *fmt,...)
55 (*svm_print_string)(buf);
58 static void info(
const char *fmt,...) {}
131 int more = len - h->
len;
135 while (
size < more )
167 if ( i>j )
swap(i,j);
171 swap(h->data[i],h->data[j]);
194 virtual double *
get_QD()
const = 0;
195 virtual void swap_index(
int i,
int j)
const = 0;
207 virtual double *
get_QD()
const = 0;
230 return dot(x[i],x[j]);
251 :kernel_type(param.kernel_type), degree(param.degree),
277 for (
int i=0; i<l; i++ ) {
341 while ( x->
index != -1 )
347 while ( y->
index != -1 )
353 return exp(-param.
gamma*sum);
396 double *alpha_,
double Cp,
double Cn,
double eps,
417 return (
y[i] > 0)?
Cp :
Cn;
423 }
else if (
alpha[i] <= 0 ) {
436 bool be_shrunk(
int i,
double Gmax1,
double Gmax2);
470 if ( 2*nr_free < active_size ) {
471 info(
"\nWARNING: using -h 0 may be faster\n");
474 if ( nr_free*l > 2*active_size*(l-active_size) ) {
475 for ( i=active_size; i<
l; i++ ) {
479 G[i] +=
alpha[j] * Q_i[j];
487 double alpha_i =
alpha[i];
488 for ( j=active_size; j<
l; j++ ) {
489 G[j] += alpha_i * Q_i[j];
497 double *alpha_,
double Cp,
double Cn,
double eps,
514 for (
int i=0; i<
l; i++ ) {
522 for (
int i=0; i<
l; i++ ) {
533 for ( i=0; i<
l; i++ ) {
537 for ( i=0; i<
l; i++ ) {
540 double alpha_i =
alpha[i];
542 for ( j=0; j<
l; j++ ) {
543 G[j] += alpha_i*Q_i[j];
546 for ( j=0; j<
l; j++ ) {
557 int max_iter =
max(10000000, l>INT_MAX/100 ? INT_MAX : 100*l);
560 while ( iter < max_iter )
564 if ( --counter == 0 ) {
565 counter =
min(l,1000);
591 double C_i =
get_C(i);
592 double C_j =
get_C(j);
594 double old_alpha_i =
alpha[i];
595 double old_alpha_j =
alpha[j];
598 double quad_coef =
QD[i]+
QD[j]+2*Q_i[j];
599 if ( quad_coef <= 0 ) {
602 double delta = (-
G[i]-
G[j])/quad_coef;
608 if ( alpha[j] < 0 ) {
613 if ( alpha[i] < 0 ) {
618 if ( diff > C_i - C_j ) {
619 if ( alpha[i] > C_i ) {
621 alpha[j] = C_i - diff;
624 if ( alpha[j] > C_j ) {
626 alpha[i] = C_j + diff;
630 double quad_coef =
QD[i]+
QD[j]-2*Q_i[j];
631 if ( quad_coef <= 0 ) {
634 double delta = (
G[i]-
G[j])/quad_coef;
640 if ( alpha[i] > C_i ) {
642 alpha[j] = sum - C_i;
645 if ( alpha[j] < 0 ) {
651 if ( alpha[j] > C_j ) {
653 alpha[i] = sum - C_j;
656 if ( alpha[i] < 0 ) {
665 double delta_alpha_i =
alpha[i] - old_alpha_i;
666 double delta_alpha_j =
alpha[j] - old_alpha_j;
669 G[k] += Q_i[k]*delta_alpha_i + Q_j[k]*delta_alpha_j;
683 for ( k=0; k<
l; k++ ) {
684 G_bar[k] -= C_i * Q_i[k];
687 for ( k=0; k<
l; k++ ) {
688 G_bar[k] += C_i * Q_i[k];
696 for ( k=0; k<
l; k++ ) {
697 G_bar[k] -= C_j * Q_j[k];
700 for ( k=0; k<
l; k++ ) {
701 G_bar[k] += C_j * Q_j[k];
708 if ( iter >= max_iter ) {
715 fprintf(stderr,
"\nWARNING: reaching max number of iterations\n");
726 for ( i=0; i<
l; i++ ) {
735 for (
int i=0; i<
l; i++ ) {
751 info(
"\noptimization finished, #iter = %d\n",iter);
775 double obj_diff_min =
INF;
780 if ( -
G[t] >= Gmax ) {
787 if (
G[t] >= Gmax ) {
798 Q_i =
Q->
get_Q(i,active_size);
804 double grad_diff=Gmax+
G[j];
805 if ( G[j] >= Gmax2 ) {
808 if ( grad_diff > 0 ) {
810 double quad_coef =
QD[i]+
QD[j]-2.0*
y[i]*Q_i[j];
811 if ( quad_coef > 0 ) {
812 obj_diff = -(grad_diff*grad_diff)/quad_coef;
814 obj_diff = -(grad_diff*grad_diff)/
TAU;
817 if ( obj_diff <= obj_diff_min ) {
819 obj_diff_min = obj_diff;
825 double grad_diff= Gmax-
G[j];
826 if ( -G[j] >= Gmax2 ) {
829 if ( grad_diff > 0 ) {
831 double quad_coef =
QD[i]+
QD[j]+2.0*
y[i]*Q_i[j];
832 if ( quad_coef > 0 ) {
833 obj_diff = -(grad_diff*grad_diff)/quad_coef;
835 obj_diff = -(grad_diff*grad_diff)/
TAU;
838 if ( obj_diff <= obj_diff_min ) {
840 obj_diff_min = obj_diff;
847 if ( Gmax+Gmax2 <
eps ) {
860 return(-
G[i] > Gmax1);
862 return(-
G[i] > Gmax2);
866 return(
G[i] > Gmax2);
868 return(
G[i] > Gmax1);
885 if ( -
G[i] >= Gmax1 ) {
890 if (
G[i] >= Gmax2 ) {
896 if ( -
G[i] >= Gmax2 ) {
901 if (
G[i] >= Gmax1 ) {
908 if (
unshrink ==
false && Gmax1 + Gmax2 <=
eps*10 ) {
918 while ( active_size > i )
920 if ( !
be_shrunk(active_size, Gmax1, Gmax2) ) {
934 double ub =
INF, lb = -
INF, sum_free = 0;
936 double yG =
y[i]*
G[i];
957 r = sum_free/nr_free;
985 bool be_shrunk(
int i,
double Gmax1,
double Gmax2,
double Gmax3,
double Gmax4);
999 double Gmaxp2 = -
INF;
1002 double Gmaxn = -
INF;
1003 double Gmaxn2 = -
INF;
1007 double obj_diff_min =
INF;
1012 if ( -
G[t] >= Gmaxp ) {
1019 if (
G[t] >= Gmaxn ) {
1029 const Qfloat *Q_ip = NULL;
1030 const Qfloat *Q_in = NULL;
1032 Q_ip =
Q->
get_Q(ip,active_size);
1035 Q_in =
Q->
get_Q(in,active_size);
1041 double grad_diff=Gmaxp+
G[j];
1042 if ( G[j] >= Gmaxp2 ) {
1045 if ( grad_diff > 0 ) {
1047 double quad_coef =
QD[ip]+
QD[j]-2*Q_ip[j];
1048 if ( quad_coef > 0 ) {
1049 obj_diff = -(grad_diff*grad_diff)/quad_coef;
1051 obj_diff = -(grad_diff*grad_diff)/
TAU;
1054 if ( obj_diff <= obj_diff_min ) {
1056 obj_diff_min = obj_diff;
1062 double grad_diff=Gmaxn-
G[j];
1063 if ( -G[j] >= Gmaxn2 ) {
1066 if ( grad_diff > 0 ) {
1068 double quad_coef =
QD[in]+
QD[j]-2*Q_in[j];
1069 if ( quad_coef > 0 ) {
1070 obj_diff = -(grad_diff*grad_diff)/quad_coef;
1072 obj_diff = -(grad_diff*grad_diff)/
TAU;
1075 if ( obj_diff <= obj_diff_min ) {
1077 obj_diff_min = obj_diff;
1084 if (
max(Gmaxp+Gmaxp2,Gmaxn+Gmaxn2) <
eps ) {
1088 if (
y[Gmin_idx] == +1 ) {
1102 return(-
G[i] > Gmax1);
1104 return(-
G[i] > Gmax4);
1108 return(
G[i] > Gmax2);
1110 return(
G[i] > Gmax3);
1119 double Gmax1 = -
INF;
1120 double Gmax2 = -
INF;
1121 double Gmax3 = -
INF;
1122 double Gmax4 = -
INF;
1129 if ( -
G[i] > Gmax1 ) Gmax1 = -
G[i];
1130 }
else if ( -
G[i] > Gmax4 ) Gmax4 = -
G[i];
1134 if (
G[i] > Gmax2 ) Gmax2 =
G[i];
1135 }
else if (
G[i] > Gmax3 ) Gmax3 =
G[i];
1139 if (
unshrink ==
false &&
max(Gmax1+Gmax2,Gmax3+Gmax4) <=
eps*10 ) {
1146 if (
be_shrunk(i, Gmax1, Gmax2, Gmax3, Gmax4) ) {
1148 while ( active_size > i )
1150 if ( !
be_shrunk(active_size, Gmax1, Gmax2, Gmax3, Gmax4) ) {
1162 int nr_free1 = 0,nr_free2 = 0;
1163 double ub1 =
INF, ub2 =
INF;
1164 double lb1 = -
INF, lb2 = -
INF;
1165 double sum_free1 = 0, sum_free2 = 0;
1170 lb1 =
max(lb1,
G[i]);
1172 ub1 =
min(ub1,
G[i]);
1179 lb2 =
max(lb2,
G[i]);
1181 ub2 =
min(ub2,
G[i]);
1190 if ( nr_free1 > 0 ) {
1191 r1 = sum_free1/nr_free1;
1196 if ( nr_free2 > 0 ) {
1197 r2 = sum_free2/nr_free2;
1213 :
Kernel(prob.l, prob.
x, param)
1217 QD =
new double[prob.
l];
1218 for (
int i=0; i<prob.
l; i++ ) {
1228 for (
int j = start; j <
len; j++ ) {
1264 :
Kernel(prob.l, prob.
x, param)
1267 QD =
new double[prob.
l];
1268 for (
int i=0; i<prob.
l; i++ ) {
1278 for (
int j=start; j<
len; j++ ) {
1315 QD =
new double[2*
l];
1318 for (
int k=0; k<
l; k++ ) {
1341 int j, real_i =
index[i];
1343 for ( j=0; j<
l; j++ ) {
1352 for ( j=0; j<
len; j++ ) {
1390 double *minus_ones =
new double[l];
1395 for ( i=0; i<l; i++ ) {
1398 if ( prob->
y[i] > 0 ) y[i] = +1;
else y[i] = -1;
1402 s.
Solve(l,
SVC_Q(*prob,*param,y), minus_ones, y,
1406 for ( i=0; i<l; i++ ) {
1407 sum_alpha += alpha[i];
1411 info(
"nu = %f\n", sum_alpha/(Cp*prob->
l));
1414 for ( i=0; i<l; i++ ) {
1418 delete[] minus_ones;
1428 double nu = param->
nu;
1432 for ( i=0; i<l; i++ ) {
1433 if ( prob->
y[i]>0 ) {
1440 double sum_pos = nu*l/2;
1441 double sum_neg = nu*l/2;
1443 for ( i=0; i<l; i++ ) {
1445 alpha[i] =
min(1.0,sum_pos);
1446 sum_pos -= alpha[i];
1448 alpha[i] =
min(1.0,sum_neg);
1449 sum_neg -= alpha[i];
1453 double *zeros =
new double[l];
1455 for ( i=0; i<l; i++ ) {
1464 info(
"C = %f\n",1/r);
1466 for ( i=0; i<l; i++ ) {
1484 double *zeros =
new double[l];
1488 int n = (
int)(param->
nu*prob->
l);
1490 for ( i=0; i<n; i++ ) {
1494 alpha[n] = param->
nu * prob->
l - n;
1496 for ( i=n+1; i<l; i++ ) {
1500 for ( i=0; i<l; i++ ) {
1518 double *alpha2 =
new double[2*l];
1519 double *linear_term =
new double[2*l];
1523 for ( i=0; i<l; i++ ) {
1525 linear_term[i] = param->
p - prob->
y[i];
1529 linear_term[i+l] = param->
p + prob->
y[i];
1534 s.
Solve(2*l,
SVR_Q(*prob,*param), linear_term, y,
1537 double sum_alpha = 0;
1538 for ( i=0; i<l; i++ ) {
1539 alpha[i] = alpha2[i] - alpha2[i+l];
1540 sum_alpha += fabs(alpha[i]);
1542 info(
"nu = %f\n",sum_alpha/(param->
C*l));
1545 delete[] linear_term;
1554 double C = param->
C;
1555 double *alpha2 =
new double[2*l];
1556 double *linear_term =
new double[2*l];
1560 double sum = C * param->
nu * l / 2;
1561 for ( i=0; i<l; i++ ) {
1562 alpha2[i] = alpha2[i+l] =
min(sum,C);
1565 linear_term[i] = - prob->
y[i];
1568 linear_term[i+l] = prob->
y[i];
1573 s.
Solve(2*l,
SVR_Q(*prob,*param), linear_term, y,
1576 info(
"epsilon = %f\n",-si->
r);
1578 for ( i=0; i<l; i++ ) {
1579 alpha[i] = alpha2[i] - alpha2[i+l];
1583 delete[] linear_term;
1598 double Cp,
double Cn)
1600 double *alpha =
Malloc(
double,prob->
l);
1627 for (
int i=0; i<prob->
l; i++ ) {
1628 if ( fabs(alpha[i]) > 0 ) {
1630 if ( prob->
y[i] > 0 ) {
1642 info(
"nSV = %d, nBSV = %d\n",nSV,nBSV);
1652 int l,
const double *dec_values,
const double *labels,
1653 double&
A,
double& B)
1655 double prior1=0, prior0 = 0;
1658 for ( i=0; i<l; i++ ) {
1659 if ( labels[i] > 0 ) prior1+=1;
1664 double min_step=1e-10;
1667 double hiTarget=(prior1+1.0)/(prior1+2.0);
1668 double loTarget=1/(prior0+2.0);
1669 double *t=
Malloc(
double,l);
1671 double newA,newB,newf,d1,d2;
1675 A=0.0; B=
log((prior0+1.0)/(prior1+1.0));
1678 for ( i=0; i<l; i++ ) {
1679 if ( labels[i]>0 ) t[i]=hiTarget;
1681 fApB = dec_values[i]*A+B;
1683 fval += t[i]*fApB +
log(1+exp(-fApB));
1685 fval += (t[i] - 1)*fApB +
log(1+exp(fApB));
1688 for ( iter=0; iter<max_iter; iter++ ) {
1692 double h21=0.0,g1=0.0,g2=0.0;
1693 for ( i=0; i<l; i++ ) {
1694 fApB = dec_values[i]*A+B;
1696 p=exp(-fApB)/(1.0+exp(-fApB));
1697 q=1.0/(1.0+exp(-fApB));
1699 p=1.0/(1.0+exp(fApB));
1700 q=exp(fApB)/(1.0+exp(fApB));
1703 h11+=dec_values[i]*dec_values[i]*d2;
1705 h21+=dec_values[i]*d2;
1707 g1+=dec_values[i]*d1;
1712 if ( fabs(g1)<eps && fabs(g2)<eps ) {
1717 double det=h11*h22-h21*h21;
1718 double dA=-(h22*g1 - h21 * g2) / det;
1719 double dB=-(-h21*g1+ h11 * g2) / det;
1720 double gd=g1*dA+g2*dB;
1723 double stepsize = 1;
1724 while ( stepsize >= min_step )
1726 newA = A + stepsize * dA;
1727 newB = B + stepsize * dB;
1731 for ( i=0; i<l; i++ ) {
1732 fApB = dec_values[i]*newA+newB;
1734 newf += t[i]*fApB +
log(1+exp(-fApB));
1736 newf += (t[i] - 1)*fApB +
log(1+exp(fApB));
1740 if ( newf<fval+0.0001*stepsize*gd ) {
1741 A=newA;B=newB;fval=newf;
1744 stepsize = stepsize / 2.0;
1748 if ( stepsize < min_step ) {
1749 info(
"Line search fails in two-class probability estimates\n");
1754 if ( iter>=max_iter ) {
1755 info(
"Reaching maximal iterations in two-class probability estimates\n");
1762 double fApB = decision_value*A+B;
1765 return exp(-fApB)/(1.0+exp(-fApB));
1767 return 1.0/(1+exp(fApB)) ;
1775 int iter = 0, max_iter=
max(100,k);
1776 double **Q=
Malloc(
double *,k);
1777 double *Qp=
Malloc(
double,k);
1780 for ( t=0; t<k; t++ ) {
1784 for ( j=0; j<t; j++ ) {
1785 Q[t][t]+=r[j][t]*r[j][t];
1788 for ( j=t+1; j<k; j++ ) {
1789 Q[t][t]+=r[j][t]*r[j][t];
1790 Q[t][j]=-r[j][t]*r[t][j];
1793 for ( iter=0; iter<max_iter; iter++ ) {
1796 for ( t=0; t<k; t++ ) {
1798 for ( j=0; j<k; j++ ) {
1799 Qp[t]+=Q[t][j]*p[j];
1804 for ( t=0; t<k; t++ ) {
1805 double error=fabs(Qp[t]-pQp);
1806 if ( error>max_error ) {
1810 if ( max_error<eps )
break;
1812 for ( t=0; t<k; t++ ) {
1813 double diff=(-Qp[t]+pQp)/Q[t][t];
1815 pQp=(pQp+diff*(diff*Q[t][t]+2*Qp[t]))/(1+diff)/(1+diff);
1816 for ( j=0; j<k; j++ ) {
1817 Qp[j]=(Qp[j]+diff*Q[t][j])/(1+diff);
1822 if ( iter>=max_iter ) {
1823 info(
"Exceeds max_iter in multiclass_prob\n");
1825 for ( t=0; t<k; t++ ) free(Q[t]);
1833 double Cp,
double Cn,
double& probA,
double& probB)
1837 int *perm =
Malloc(
int,prob->
l);
1838 double *dec_values =
Malloc(
double,prob->
l);
1841 for ( i=0; i<prob->
l; i++ ) perm[i]=i;
1842 for ( i=0; i<prob->
l; i++ ) {
1843 int j = i+rand()%(prob->
l-i);
1844 swap(perm[i],perm[j]);
1846 for ( i=0; i<nr_fold; i++ ) {
1847 int begin = i*prob->
l/nr_fold;
1848 int end = (i+1)*prob->
l/nr_fold;
1852 subprob.
l = prob->
l-(end-begin);
1854 subprob.y =
Malloc(
double,subprob.l);
1857 for ( j=0; j<
begin; j++ ) {
1858 subprob.x[k] = prob->
x[perm[j]];
1859 subprob.y[k] = prob->
y[perm[j]];
1862 for ( j=end; j<prob->
l; j++ ) {
1863 subprob.x[k] = prob->
x[perm[j]];
1864 subprob.y[k] = prob->
y[perm[j]];
1867 int p_count=0,n_count=0;
1868 for ( j=0; j<k; j++ ) {
1869 if ( subprob.y[j]>0 ) {
1876 if ( p_count==0 && n_count==0 ) {
1877 for ( j=begin; j<
end; j++ ) {
1878 dec_values[perm[j]] = 0;
1880 }
else if ( p_count > 0 && n_count == 0 ) {
1881 for ( j=begin; j<
end; j++ ) {
1882 dec_values[perm[j]] = 1;
1884 }
else if ( p_count == 0 && n_count > 0 ) {
1885 for ( j=begin; j<
end; j++ ) {
1886 dec_values[perm[j]] = -1;
1900 for ( j=begin; j<
end; j++ ) {
1903 dec_values[perm[j]] *= submodel->
label[0];
1922 double *ymv =
Malloc(
double,prob->
l);
1928 for ( i=0; i<prob->
l; i++ ) {
1929 ymv[i]=prob->
y[i]-ymv[i];
1930 mae += fabs(ymv[i]);
1933 double std=sqrt(2*mae*mae);
1936 for ( i=0; i<prob->
l; i++ ) {
1937 if ( fabs(ymv[i]) > 5*std ) {
1944 info(
"Prob. model for test data: target value = predicted value + z,\nz: Laplace distribution e^(-|z|/sigma)/(2sigma),sigma= %g\n",mae);
1955 int max_nr_class = 16;
1959 int *data_label =
Malloc(
int,l);
1962 for ( i = 0; i <
l; i++ ) {
1963 int this_label = (
int )prob->
y[ i ];
1966 if ( this_label == label[ j ] ) {
1971 data_label[ i ] = j;
1972 if ( j == nr_class ) {
1973 if ( nr_class == max_nr_class ) {
1976 int *new_label_data =
static_cast< int *
>( realloc( label, max_nr_class *
sizeof(
int ) ) );
1977 if ( new_label_data == NULL ) {
1978 info(
"\n\n!!! Critical memory error in svm_group_classes, label allocation !!!\n\n" );
1980 label = new_label_data;
1983 int *new_count_data =
static_cast< int *
>( realloc( count, max_nr_class *
sizeof(
int ) ) );
1984 if ( new_count_data == NULL ) {
1985 info(
"\n\n!!! Critical memory error in svm_group_classes, count allocation !!!\n\n" );
1987 count = new_count_data;
1999 start[ i ] = start[ i - 1 ] + count[ i - 1 ];
2001 for ( i = 0; i <
l; i++ ) {
2002 perm[ start[ data_label[ i ] ] ] = i;
2003 ++start[ data_label[ i ] ];
2007 start[ i ] = start[ i - 1 ] + count[ i - 1 ];
2031 model->
label = NULL;
2049 for ( i=0; i<prob->
l; i++ ) {
2057 for ( i=0; i<prob->
l; i++ ) {
2058 if ( fabs(f.
alpha[i]) > 0 ) {
2059 model->
SV[j] = prob->
x[i];
2074 int *perm =
Malloc(
int,l);
2078 if ( nr_class == 1 ) {
2079 info(
"WARNING: training data in only one class. See README for details.\n");
2084 for ( i=0; i<
l; i++ ) {
2085 x[i] = prob->
x[perm[i]];
2090 double *weighted_C =
Malloc(
double, nr_class);
2092 weighted_C[i] = param->
C;
2101 if ( j == nr_class ) {
2102 fprintf(stderr,
"WARNING: class label %d specified in weight is not found\n", param->
weight_label[i]);
2104 weighted_C[j] *= param->
weight[i];
2110 bool *nonzero =
Malloc(
bool,l);
2111 for ( i=0; i<
l; i++ ) {
2118 probA=
Malloc(
double,nr_class*(nr_class-1)/2);
2119 probB=
Malloc(
double,nr_class*(nr_class-1)/2);
2124 for (
int j=i+1; j<
nr_class; j++ ) {
2126 int si = start[i], sj = start[j];
2127 int ci = count[i], cj = count[j];
2130 sub_prob.
y =
Malloc(
double,sub_prob.
l);
2132 for ( k=0; k<ci; k++ ) {
2133 sub_prob.
x[k] = x[si+k];
2136 for ( k=0; k<cj; k++ ) {
2137 sub_prob.
x[ci+k] = x[sj+k];
2138 sub_prob.
y[ci+k] = -1;
2145 f[
p] =
svm_train_one(&sub_prob,param,weighted_C[i],weighted_C[j]);
2146 for ( k=0; k<ci; k++ ) {
2147 if ( !nonzero[si+k] && fabs(f[p].alpha[k]) > 0 ) {
2148 nonzero[si+k] =
true;
2151 for ( k=0; k<cj; k++ ) {
2152 if ( !nonzero[sj+k] && fabs(f[p].alpha[ci+k]) > 0 ) {
2153 nonzero[sj+k] =
true;
2168 model->
label[i] = label[i];
2171 model->
rho =
Malloc(
double,nr_class*(nr_class-1)/2);
2172 for ( i=0; i<nr_class*(nr_class-1)/2; i++ ) {
2173 model->
rho[i] = f[i].
rho;
2177 model->
probA =
Malloc(
double,nr_class*(nr_class-1)/2);
2178 model->
probB =
Malloc(
double,nr_class*(nr_class-1)/2);
2179 for ( i=0; i<nr_class*(nr_class-1)/2; i++ ) {
2180 model->
probA[i] = probA[i];
2181 model->
probB[i] = probB[i];
2189 int *nz_count =
Malloc(
int,nr_class);
2193 for (
int j=0; j<count[i]; j++ ) {
2194 if ( nonzero[start[i]+j] ) {
2203 info(
"Total nSV = %d\n",total_sv);
2205 model->
l = total_sv;
2209 for ( i=0; i<
l; i++ ) {
2211 model->
SV[
p] = x[i];
2216 int *nz_start =
Malloc(
int,nr_class);
2219 nz_start[i] = nz_start[i-1]+nz_count[i-1];
2223 for ( i=0; i<nr_class-1; i++ ) {
2229 for (
int j=i+1; j<
nr_class; j++ ) {
2239 int q = nz_start[i];
2241 for ( k=0; k<ci; k++ ) {
2242 if ( nonzero[si+k] ) {
2247 for ( k=0; k<cj; k++ ) {
2248 if ( nonzero[sj+k] ) {
2265 for ( i=0; i<nr_class*(nr_class-1)/2; i++ ) {
2279 int *fold_start =
Malloc(
int,nr_fold+1);
2281 int *perm =
Malloc(
int,l);
2294 int *fold_count =
Malloc(
int,nr_fold);
2297 for ( i=0; i<
l; i++ ) {
2301 for ( i=0; i<count[c]; i++ ) {
2302 int j = i+rand()%(count[c]-i);
2303 swap(index[start[c]+j],index[start[c]+i]);
2306 for ( i=0; i<nr_fold; i++ ) {
2309 fold_count[i]+=(i+1)*count[c]/nr_fold-i*count[c]/nr_fold;
2313 for ( i=1; i<=nr_fold; i++ ) {
2314 fold_start[i] = fold_start[i-1]+fold_count[i-1];
2317 for ( i=0; i<nr_fold; i++ ) {
2318 int begin = start[c]+i*count[c]/nr_fold;
2319 int end = start[c]+(i+1)*count[c]/nr_fold;
2320 for (
int j=begin; j<
end; j++ ) {
2321 perm[fold_start[i]] = index[j];
2327 for ( i=1; i<=nr_fold; i++ ) {
2328 fold_start[i] = fold_start[i-1]+fold_count[i-1];
2336 for ( i=0; i<
l; i++ ) perm[i]=i;
2337 for ( i=0; i<
l; i++ ) {
2338 int j = i+rand()%(l-i);
2339 swap(perm[i],perm[j]);
2341 for ( i=0; i<=nr_fold; i++ ) {
2342 fold_start[i]=i*l/nr_fold;
2346 for ( i=0; i<nr_fold; i++ ) {
2347 int begin = fold_start[i];
2348 int end = fold_start[i+1];
2352 subprob.
l = l-(end-
begin);
2354 subprob.
y =
Malloc(
double,subprob.
l);
2357 for ( j=0; j<
begin; j++ ) {
2358 subprob.
x[k] = prob->
x[perm[j]];
2359 subprob.
y[k] = prob->
y[perm[j]];
2362 for ( j=end; j<
l; j++ ) {
2363 subprob.
x[k] = prob->
x[perm[j]];
2364 subprob.
y[k] = prob->
y[perm[j]];
2371 for ( j=begin; j<
end; j++ ) {
2374 free(prob_estimates);
2376 for ( j=begin; j<
end; j++ ) {
2377 target[perm[j]] =
svm_predict(submodel,prob->
x[perm[j]]);
2401 if ( model->
label != NULL ) {
2402 for (
int i=0; i<model->
nr_class; i++ ) {
2403 label[i] = model->
label[i];
2411 for (
int i=0; i<model->
l; i++ ) {
2425 model->
probA!=NULL ) {
2426 return model->
probA[0];
2428 fprintf(stderr,
"Model doesn't contain information for SVR probability inference\n");
2441 for ( i=0; i<model->
l; i++ ) {
2444 sum -= model->
rho[0];
2448 return (sum>0)?1:-1;
2456 double *kvalue =
Malloc(
double,l);
2457 for ( i=0; i<
l; i++ ) {
2464 start[i] = start[i-1]+model->
nSV[i-1];
2467 int *vote =
Malloc(
int,nr_class);
2474 for (
int j=i+1; j<
nr_class; j++ ) {
2478 int ci = model->
nSV[i];
2479 int cj = model->
nSV[j];
2482 double *coef1 = model->
sv_coef[j-1];
2483 double *coef2 = model->
sv_coef[i];
2484 for ( k=0; k<ci; k++ ) {
2485 sum += coef1[si+k] * kvalue[si+k];
2487 for ( k=0; k<cj; k++ ) {
2488 sum += coef2[sj+k] * kvalue[sj+k];
2490 sum -= model->
rho[
p];
2491 dec_values[
p] =
sum;
2493 if ( dec_values[p] > 0 ) {
2502 int vote_max_idx = 0;
2504 if ( vote[i] > vote[vote_max_idx] ) {
2512 return model->
label[vote_max_idx];
2523 dec_values =
Malloc(
double, 1);
2525 dec_values =
Malloc(
double, nr_class*(nr_class-1)/2);
2539 double *dec_values =
Malloc(
double, nr_class*(nr_class-1)/2);
2542 double min_prob=1e-7;
2543 double **pairwise_prob=
Malloc(
double *,nr_class);
2545 pairwise_prob[i]=
Malloc(
double,nr_class);
2549 for (
int j=i+1; j<
nr_class; j++ ) {
2551 pairwise_prob[j][i]=1-pairwise_prob[i][j];
2557 int prob_max_idx = 0;
2559 if ( prob_estimates[i] > prob_estimates[prob_max_idx] ) {
2564 free(pairwise_prob[i]);
2567 free(pairwise_prob);
2568 return model->
label[prob_max_idx];
2576 "c_svc",
"nu_svc",
"one_class",
"epsilon_svr",
"nu_svr",NULL
2581 "linear",
"polynomial",
"rbf",
"sigmoid",
"precomputed",NULL
2586 FILE *fp = fopen(model_file_name,
"w");
2587 if ( fp==NULL )
return -1;
2589 char *old_locale = strdup(setlocale(LC_ALL, NULL));
2590 setlocale(LC_ALL,
"C");
2598 fprintf(fp,
"degree %d\n", param.
degree);
2602 fprintf(fp,
"gamma %g\n", param.
gamma);
2606 fprintf(fp,
"coef0 %g\n", param.
coef0);
2611 fprintf(fp,
"nr_class %d\n", nr_class);
2612 fprintf(fp,
"total_sv %d\n",l);
2616 for (
int i=0; i<nr_class*(nr_class-1)/2; i++ ) {
2617 fprintf(fp,
" %g",model->
rho[i]);
2622 if ( model->
label ) {
2623 fprintf(fp,
"label");
2625 fprintf(fp,
" %d",model->
label[i]);
2630 if ( model->
probA ) {
2631 fprintf(fp,
"probA");
2632 for (
int i=0; i<nr_class*(nr_class-1)/2; i++ ) {
2633 fprintf(fp,
" %g",model->
probA[i]);
2637 if ( model->
probB ) {
2638 fprintf(fp,
"probB");
2639 for (
int i=0; i<nr_class*(nr_class-1)/2; i++ ) {
2640 fprintf(fp,
" %g",model->
probB[i]);
2646 fprintf(fp,
"nr_sv");
2648 fprintf(fp,
" %d",model->
nSV[i]);
2653 fprintf(fp,
"SV\n");
2657 for (
int i=0; i<
l; i++ ) {
2658 for (
int j=0; j<nr_class-1; j++ ) {
2659 fprintf(fp,
"%.16g ",sv_coef[j][i]);
2665 fprintf(fp,
"0:%d ",(
int)(p->
value));
2667 while ( p->
index != -1 )
2676 setlocale(LC_ALL, old_locale);
2679 if ( ferror(fp) != 0 || fclose(fp) != 0 )
return -1;
2688 if ( fgets(
line,max_line_len,input) == NULL ) {
2692 while ( strrchr(
line,
'\n') == NULL )
2695 char * newline = (
char *) realloc(
line,max_line_len);
2699 if ( fgets(
line+len,max_line_len-len,input) == NULL ) {
2708 FILE *fp = fopen(model_file_name,
"rb");
2709 if ( fp==NULL )
return NULL;
2711 char *old_locale = strdup(setlocale(LC_ALL, NULL));
2712 setlocale(LC_ALL,
"C");
2719 model->
probA = NULL;
2720 model->
probB = NULL;
2721 model->
label = NULL;
2727 if ( fscanf(fp,
"%80s",cmd) == EOF ) {
2728 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2731 if ( strcmp(cmd,
"svm_type")==0 ) {
2732 if ( fscanf(fp,
"%80s",cmd) == EOF ) {
2733 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2743 fprintf(stderr,
"unknown svm type.\n");
2745 setlocale(LC_ALL, old_locale);
2753 }
else if ( strcmp(cmd,
"kernel_type")==0 ) {
2754 if ( fscanf(fp,
"%80s",cmd) == EOF ) {
2755 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2765 fprintf(stderr,
"unknown kernel function.\n");
2767 setlocale(LC_ALL, old_locale);
2775 }
else if ( strcmp(cmd,
"degree")==0 ) {
2776 if ( fscanf(fp,
"%d",¶m.
degree) == EOF ) {
2777 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2779 }
else if ( strcmp(cmd,
"gamma")==0 ) {
2780 if ( fscanf(fp,
"%lf",¶m.
gamma) == EOF ) {
2781 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2783 }
else if ( strcmp(cmd,
"coef0")==0 ) {
2784 if ( fscanf(fp,
"%lf",¶m.
coef0) == EOF ) {
2785 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2787 }
else if ( strcmp(cmd,
"nr_class")==0 ) {
2788 if ( fscanf(fp,
"%d",&model->
nr_class) == EOF ) {
2789 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2791 }
else if ( strcmp(cmd,
"total_sv")==0 ) {
2792 if ( fscanf(fp,
"%d",&model->
l) == EOF ) {
2793 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2795 }
else if ( strcmp(cmd,
"rho")==0 ) {
2798 for (
int i=0; i<n; i++ ) {
2799 if ( fscanf(fp,
"%lf",&model->
rho[i]) == EOF ) {
2800 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2803 }
else if ( strcmp(cmd,
"label")==0 ) {
2806 for (
int i=0; i<n; i++ ) {
2807 if ( fscanf(fp,
"%d",&model->
label[i]) == EOF ) {
2808 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2811 }
else if ( strcmp(cmd,
"probA")==0 ) {
2814 for (
int i=0; i<n; i++ ) {
2815 if ( fscanf(fp,
"%lf",&model->
probA[i]) == EOF ) {
2816 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2819 }
else if ( strcmp(cmd,
"probB")==0 ) {
2822 for (
int i=0; i<n; i++ ) {
2823 if ( fscanf(fp,
"%lf",&model->
probB[i]) == EOF ) {
2824 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2827 }
else if ( strcmp(cmd,
"nr_sv")==0 ) {
2830 for (
int i=0; i<n; i++ ) {
2831 if ( fscanf(fp,
"%d",&model->
nSV[i]) == EOF ) {
2832 std::cout <<
"Warning! End of file reached without any matches." << std::endl;
2835 }
else if ( strcmp(cmd,
"SV")==0 ) {
2839 if ( c==EOF || c==
'\n' )
break;
2843 fprintf(stderr,
"unknown text in model file: [%s]\n",cmd);
2845 setlocale(LC_ALL, old_locale);
2858 long pos = ftell(fp);
2860 max_line_len = 1024;
2862 char *
p,*endptr,*idx,*val;
2866 p = strtok(
line,
":");
2869 p = strtok(NULL,
":");
2876 elements += model->
l;
2878 fseek(fp,pos,SEEK_SET);
2884 for ( i=0; i<m; i++ ) {
2892 for ( i=0; i<
l; i++ ) {
2894 model->
SV[i] = &x_space[j];
2896 p = strtok(
line,
" \t");
2897 model->
sv_coef[0][i] = strtod(p,&endptr);
2898 for (
int k=1; k<m; k++ ) {
2899 p = strtok(NULL,
" \t");
2900 model->
sv_coef[k][i] = strtod(p,&endptr);
2905 idx = strtok(NULL,
":");
2906 val = strtok(NULL,
" \t");
2908 if ( val == NULL ) {
2911 x_space[j].
index = (
int) strtol(idx,&endptr,10);
2912 x_space[j].
value = strtod(val,&endptr);
2916 x_space[j++].
index = -1;
2920 setlocale(LC_ALL, old_locale);
2923 if ( ferror(fp) != 0 || fclose(fp) != 0 ) {
2933 if ( model_ptr->
free_sv && model_ptr->
l > 0 && model_ptr->
SV != NULL ) {
2934 free((
void *)(model_ptr->
SV[0]));
2937 for (
int i=0; i<model_ptr->
nr_class-1; i++ ) {
2942 free(model_ptr->
SV);
2943 model_ptr->
SV = NULL;
2948 free(model_ptr->
rho);
2949 model_ptr->
rho = NULL;
2951 free(model_ptr->
label);
2952 model_ptr->
label= NULL;
2954 free(model_ptr->
probA);
2955 model_ptr->
probA = NULL;
2957 free(model_ptr->
probB);
2958 model_ptr->
probB= NULL;
2960 free(model_ptr->
nSV);
2961 model_ptr->
nSV = NULL;
2966 if ( model_ptr_ptr != NULL && *model_ptr_ptr != NULL ) {
2968 free(*model_ptr_ptr);
2969 *model_ptr_ptr = NULL;
2984 if ( svm_type !=
C_SVC &&
2989 return "unknown svm type";
2995 if ( kernel_type !=
LINEAR &&
2996 kernel_type !=
POLY &&
2997 kernel_type !=
RBF &&
3000 return "unknown kernel type";
3003 if ( param->
gamma < 0 ) {
3007 if ( param->
degree < 0 ) {
3008 return "degree of polynomial kernel < 0";
3014 return "cache_size <= 0";
3017 if ( param->
eps <= 0 ) {
3021 if ( svm_type ==
C_SVC ||
3024 if ( param->
C <= 0 ) {
3029 if ( svm_type ==
NU_SVC ||
3032 if ( param->
nu <= 0 || param->
nu > 1 ) {
3033 return "nu <= 0 or nu > 1";
3038 if ( param->
p < 0 ) {
3045 return "shrinking != 0 and shrinking != 1";
3050 return "probability != 0 and probability != 1";
3055 return "one-class SVM probability output not supported yet";
3061 if ( svm_type ==
NU_SVC ) {
3063 int max_nr_class = 16;
3069 for ( i=0; i<
l; i++ ) {
3070 int this_label = (
int)prob->
y[i];
3073 if ( this_label == label[j] ) {
3078 if ( j == nr_class ) {
3079 if ( nr_class == max_nr_class ) {
3082 int *new_label_data =
static_cast< int *
>( realloc( label, max_nr_class *
sizeof(
int ) ) );
3083 if ( new_label_data == NULL ) {
3084 info(
"\n\n!!! Critical memory error in svm_group_classes, label allocation !!!\n\n" );
3086 label = new_label_data;
3089 int *new_count_data =
static_cast< int *
>( realloc( count, max_nr_class *
sizeof(
int ) ) );
3090 if ( new_count_data == NULL ) {
3091 info(
"\n\n!!! Critical memory error in svm_group_classes, count allocation !!!\n\n" );
3093 count = new_count_data;
3104 for (
int j=i+1; j<
nr_class; j++ ) {
3106 if ( param->
nu*(n1+n2)/2 >
min(n1,n2) ) {
3109 return "specified nu is infeasible";
3125 model->
probA!=NULL);
3130 if ( print_func == NULL ) {
void update_alpha_status(int i)
SVC_Q(const svm_problem &prob, const svm_parameter ¶m, const schar *y_)
static void sigmoid_train(int l, const double *dec_values, const double *labels, double &A, double &B)
const char * svm_check_parameter(const svm_problem *prob, const svm_parameter *param)
static double dot(const svm_node *px, const svm_node *py)
void svm_destroy_param(svm_parameter *param)
virtual void do_shrinking()
double kernel_rbf(int i, int j) const
static decision_function svm_train_one(const svm_problem *prob, const svm_parameter *param, double Cp, double Cn)
void svm_get_sv_indices(const svm_model *model, int *indices)
static double powi(double base, int times)
Kernel(int l, svm_node *const *x, const svm_parameter ¶m)
void Solve(int l, const QMatrix &Q, const double *p_, const schar *y_, double *alpha_, double Cp, double Cn, double eps, SolutionInfo *si, int shrinking)
virtual void swap_index(int i, int j) const
virtual void swap_index(int i, int j) const =0
int svm_check_probability_model(const svm_model *model)
static void swap(T &x, T &y)
void swap_index(int i, int j) const
static double svm_svr_probability(const svm_problem *prob, const svm_parameter *param)
virtual Qfloat * get_Q(int column, int len) const =0
ONE_CLASS_Q(const svm_problem &prob, const svm_parameter ¶m)
static void solve_c_svc(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si, double Cp, double Cn)
utility::keys::lookup::end< KeyType > const end
void svm_free_and_destroy_model(svm_model **model_ptr_ptr)
double kernel_precomputed(int i, int j) const
double svm_predict_values(const svm_model *model, const svm_node *x, double *dec_values)
void swap_index(int i, int j) const
Qfloat * get_Q(int i, int len) const
void svm_cross_validation(const svm_problem *prob, const svm_parameter *param, int nr_fold, double *target)
int svm_save_model(const char *model_file_name, const svm_model *model)
double svm_get_svr_probability(const svm_model *model)
virtual int select_working_set(int &i, int &j)
static void info(const char *fmt,...)
double log(double x, double base)
Computes log(x) in the given base.
static double k_function(const svm_node *x, const svm_node *y, const svm_parameter ¶m)
static void solve_nu_svr(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si)
Fstring::size_type len(Fstring const &s)
Length.
Fstring::size_type index(Fstring const &s, Fstring const &ss)
First Index Position of a Substring in an Fstring.
static void solve_nu_svc(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si)
svm_model * svm_load_model(const char *model_file_name)
virtual double calculate_rho()
bool be_shrunk(int i, double Gmax1, double Gmax2)
void svm_set_print_string_function(void(*print_func)(const char *))
void swap_index(int i, int j)
Qfloat * get_Q(int i, int len) const
void swap_index(int i, int j)
Real sum(ddGs &scores_to_sum)
SVR_Q(const svm_problem &prob, const svm_parameter ¶m)
double svm_predict(const svm_model *model, const svm_node *x)
void lru_insert(head_t *h)
static void multiclass_probability(int k, double **r, double *p)
Cache(int l, long int size)
void reconstruct_gradient()
static void svm_binary_svc_probability(const svm_problem *prob, const svm_parameter *param, double Cp, double Cn, double &probA, double &probB)
int get_data(const int index, Qfloat **data, int len)
static void svm_group_classes(const svm_problem *prob, int *nr_class_ret, int **label_ret, int **start_ret, int **count_ret, int *perm)
static double sigmoid_predict(double decision_value, double A, double B)
int select_working_set(int &i, int &j)
static const char * kernel_type_table[]
double(Kernel::* kernel_function)(int i, int j) const
bool be_shrunk(int i, double Gmax1, double Gmax2, double Gmax3, double Gmax4)
int svm_get_nr_class(const svm_model *model)
int svm_get_svm_type(const svm_model *model)
struct svm_parameter param
void svm_get_labels(const svm_model *model, int *label)
double kernel_linear(int i, int j) const
svm_model * svm_train(const svm_problem *prob, const svm_parameter *param)
static char * readline(FILE *input)
static void(* svm_print_string)(const char *)
void lru_delete(head_t *h)
ocstream cout(std::cout)
Wrapper around std::cout.
double svm_predict_probability(const svm_model *model, const svm_node *x, double *prob_estimates)
static const char * svm_type_table[]
virtual Qfloat * get_Q(int column, int len) const =0
utility::keys::lookup::begin< KeyType > const begin
static void solve_one_class(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si)
virtual double * get_QD() const =0
double kernel_sigmoid(int i, int j) const
Qfloat * get_Q(int i, int len) const
int svm_get_nr_sv(const svm_model *model)
void Solve(int l, const QMatrix &Q, const double *p, const schar *y, double *alpha, double Cp, double Cn, double eps, SolutionInfo *si, int shrinking)
virtual double * get_QD() const =0
bool is_upper_bound(int i)
void swap_index(int i, int j) const
static void clone(T *&dst, S *src, int n)
static void solve_epsilon_svr(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si)
bool is_lower_bound(int i)
void svm_free_model_content(svm_model *model_ptr)
double kernel_poly(int i, int j) const
static void print_string_stdout(const char *s)