53 template <
class T>
static inline T
min(T x,T y) {
return (x<y)?x:y; }
56 template <
class T>
static inline T
max(T x,T y) {
return (x>y)?x:y; }
58 template <
class T>
static inline void swap(T& x, T& y) { T t=x; x=y; y=t; }
59 template <
class S,
class T>
static inline void clone(T*& dst, S* src,
int n)
62 memcpy((
void *)dst,(
void *)src,
sizeof(T)*n);
64 static inline double powi(
double base,
int times)
66 double tmp = base, ret = 1.0;
68 for(
int t=times; t>0; t/=2)
77 #define Malloc(type,n) (type *)malloc((n)*sizeof(type)) 86 static void info(
const char *fmt,...)
93 (*svm_print_string)(buf);
96 static void info(
const char *fmt,...) {}
108 Cache(
int l,
long int size);
114 int get_data(
const int index,
Qfloat **data,
int len);
115 void swap_index(
int i,
int j);
128 void lru_delete(head_t *h);
129 void lru_insert(head_t *h);
132 Cache::Cache(
int l_,
long int size_):l(l_),size(size_)
134 head = (head_t *)calloc(l,
sizeof(head_t));
136 size -= l *
sizeof(head_t) /
sizeof(
Qfloat);
137 size =
max(size, 2 * (
long int) l);
138 lru_head.next = lru_head.prev = &lru_head;
143 for(head_t *h = lru_head.next; h != &lru_head; h=h->next)
148 void Cache::lru_delete(head_t *h)
151 h->prev->next = h->next;
152 h->next->prev = h->prev;
155 void Cache::lru_insert(head_t *h)
159 h->prev = lru_head.prev;
164 int Cache::get_data(
const int index,
Qfloat **data,
int len)
166 head_t *h = &head[index];
167 if(h->len) lru_delete(h);
168 int more = len - h->len;
175 head_t *old = lru_head.next;
184 h->data = (
Qfloat *)realloc(h->data,
sizeof(
Qfloat)*len);
194 void Cache::swap_index(
int i,
int j)
198 if(head[i].len) lru_delete(&head[i]);
199 if(head[j].len) lru_delete(&head[j]);
200 swap(head[i].data,head[j].data);
201 swap(head[i].len,head[j].len);
202 if(head[i].len) lru_insert(&head[i]);
203 if(head[j].len) lru_insert(&head[j]);
206 for(head_t *h = lru_head.next; h!=&lru_head; h=h->next)
211 swap(h->data[i],h->data[j]);
234 virtual Qfloat *get_Q(
int column,
int len)
const = 0;
235 virtual double *get_QD()
const = 0;
236 virtual void swap_index(
int i,
int j)
const = 0;
237 virtual ~QMatrix() {}
240 class Kernel:
public QMatrix {
247 Qfloat *get_Q(
int column,
int len)
const override = 0;
248 double *get_QD()
const override = 0;
249 void swap_index(
int i,
int j)
const override 252 if(x_square)
swap(x_square[i],x_square[j]);
256 double (Kernel::*kernel_function)(
int i,
int j)
const;
263 const int kernel_type;
269 double kernel_linear(
int i,
int j)
const 271 return dot(x[i],x[j]);
273 double kernel_poly(
int i,
int j)
const 275 return powi(gamma*dot(x[i],x[j])+coef0,degree);
277 double kernel_rbf(
int i,
int j)
const 279 return exp(-gamma*(x_square[i]+x_square[j]-2*dot(x[i],x[j])));
281 double kernel_sigmoid(
int i,
int j)
const 283 return tanh(gamma*dot(x[i],x[j])+coef0);
285 double kernel_precomputed(
int i,
int j)
const 287 return x[i][(int)(x[j][0].value)].
value;
298 kernel_function = &Kernel::kernel_linear;
301 kernel_function = &Kernel::kernel_poly;
304 kernel_function = &Kernel::kernel_rbf;
307 kernel_function = &Kernel::kernel_sigmoid;
310 kernel_function = &Kernel::kernel_precomputed;
316 if(kernel_type ==
RBF)
318 x_square =
new double[l];
320 x_square[i] = dot(x[i],x[i]);
390 while(x->
index != -1)
396 while(y->
index != -1)
402 return exp(-param.
gamma*sum);
405 return tanh(param.
gamma*dot(x,y)+param.
coef0);
434 virtual ~Solver() {};
436 struct SolutionInfo {
443 void Solve(
int l,
const QMatrix& Q,
const double *p_,
const schar *y_,
444 double *alpha_,
const double* C_,
double eps,
445 SolutionInfo* si,
int shrinking);
450 enum { LOWER_BOUND, UPPER_BOUND, FREE };
468 void update_alpha_status(
int i)
470 if(alpha[i] >= get_C(i))
471 alpha_status[i] = UPPER_BOUND;
472 else if(alpha[i] <= 0)
473 alpha_status[i] = LOWER_BOUND;
474 else alpha_status[i] = FREE;
476 bool is_upper_bound(
int i) {
return alpha_status[i] == UPPER_BOUND; }
477 bool is_lower_bound(
int i) {
return alpha_status[i] == LOWER_BOUND; }
478 bool is_free(
int i) {
return alpha_status[i] == FREE; }
479 void swap_index(
int i,
int j);
480 void reconstruct_gradient();
481 virtual int select_working_set(
int &i,
int &j);
482 virtual double calculate_rho();
483 virtual void do_shrinking();
485 bool be_shrunk(
int i,
double Gmax1,
double Gmax2);
488 void Solver::swap_index(
int i,
int j)
493 swap(alpha_status[i],alpha_status[j]);
494 swap(alpha[i],alpha[j]);
496 swap(active_set[i],active_set[j]);
497 swap(G_bar[i],G_bar[j]);
501 void Solver::reconstruct_gradient()
505 if(active_size == l)
return;
510 for(j=active_size;j<l;j++)
511 G[j] = G_bar[j] + p[j];
513 for(j=0;j<active_size;j++)
517 if(2*nr_free < active_size)
518 info(
"\nWARNING: using -h 0 may be faster\n");
520 if (nr_free*l > 2*active_size*(l-active_size))
522 for(i=active_size;i<l;i++)
524 const Qfloat *Q_i = Q->get_Q(i,active_size);
525 for(j=0;j<active_size;j++)
527 G[i] += alpha[j] * Q_i[j];
532 for(i=0;i<active_size;i++)
535 const Qfloat *Q_i = Q->get_Q(i,l);
536 double alpha_i = alpha[i];
537 for(j=active_size;j<l;j++)
538 G[j] += alpha_i * Q_i[j];
543 void Solver::Solve(
int l,
const QMatrix& Q,
const double *p_,
const schar *y_,
544 double *alpha_,
const double* C_,
double eps,
545 SolutionInfo* si,
int shrinking)
552 clone(alpha,alpha_,l);
559 alpha_status =
new char[l];
561 update_alpha_status(i);
566 active_set =
new int[l];
575 G_bar =
new double[l];
583 if(!is_lower_bound(i))
585 const Qfloat *Q_i = Q.get_Q(i,l);
586 double alpha_i = alpha[i];
589 G[j] += alpha_i*Q_i[j];
590 if(is_upper_bound(i))
592 G_bar[j] += get_C(i) * Q_i[j];
599 int max_iter =
max(10000000, l>INT_MAX/100 ? INT_MAX : 100*l);
600 int counter =
min(l,1000)+1;
602 while(iter < max_iter)
608 counter =
min(l,1000);
609 if(shrinking) do_shrinking();
614 if(select_working_set(i,j)!=0)
617 reconstruct_gradient();
621 if(select_working_set(i,j)!=0)
631 const Qfloat *Q_i = Q.get_Q(i,active_size);
632 const Qfloat *Q_j = Q.get_Q(j,active_size);
634 double C_i = get_C(i);
635 double C_j = get_C(j);
637 double old_alpha_i = alpha[i];
638 double old_alpha_j = alpha[j];
642 double quad_coef = QD[i]+QD[j]+2*Q_i[j];
645 double delta = (-G[i]-G[j])/quad_coef;
646 double diff = alpha[i] - alpha[j];
671 alpha[j] = C_i - diff;
679 alpha[i] = C_j + diff;
685 double quad_coef = QD[i]+QD[j]-2*Q_i[j];
688 double delta = (G[i]-G[j])/quad_coef;
689 double sum = alpha[i] + alpha[j];
698 alpha[j] = sum - C_i;
714 alpha[i] = sum - C_j;
729 double delta_alpha_i = alpha[i] - old_alpha_i;
730 double delta_alpha_j = alpha[j] - old_alpha_j;
732 for(
int k=0;
k<active_size;
k++)
734 G[
k] += Q_i[
k]*delta_alpha_i + Q_j[
k]*delta_alpha_j;
740 bool ui = is_upper_bound(i);
741 bool uj = is_upper_bound(j);
742 update_alpha_status(i);
743 update_alpha_status(j);
745 if(ui != is_upper_bound(i))
750 G_bar[k] -= C_i * Q_i[k];
753 G_bar[k] += C_i * Q_i[k];
756 if(uj != is_upper_bound(j))
761 G_bar[k] -= C_j * Q_j[k];
764 G_bar[k] += C_j * Q_j[k];
774 reconstruct_gradient();
778 fprintf(stderr,
"\nWARNING: reaching max number of iterations\n");
783 si->rho = calculate_rho();
790 v += alpha[i] * (G[i] + p[i]);
798 alpha_[active_set[i]] = alpha[i];
810 si->upper_bound[i] = C[i];
812 info(
"\noptimization finished, #iter = %d\n",iter);
818 delete[] alpha_status;
825 int Solver::select_working_set(
int &out_i,
int &out_j)
837 double obj_diff_min =
INF;
839 for(
int t=0;t<active_size;t++)
842 if(!is_upper_bound(t))
851 if(!is_lower_bound(t))
860 const Qfloat *Q_i =
nullptr;
862 Q_i = Q->get_Q(i,active_size);
864 for(
int j=0;j<active_size;j++)
868 if (!is_lower_bound(j))
870 double grad_diff=Gmax+G[j];
876 double quad_coef = QD[i]+QD[j]-2.0*y[i]*Q_i[j];
878 obj_diff = -(grad_diff*grad_diff)/quad_coef;
880 obj_diff = -(grad_diff*grad_diff)/
TAU;
882 if (obj_diff <= obj_diff_min)
885 obj_diff_min = obj_diff;
892 if (!is_upper_bound(j))
894 double grad_diff= Gmax-G[j];
900 double quad_coef = QD[i]+QD[j]+2.0*y[i]*Q_i[j];
902 obj_diff = -(grad_diff*grad_diff)/quad_coef;
904 obj_diff = -(grad_diff*grad_diff)/
TAU;
906 if (obj_diff <= obj_diff_min)
909 obj_diff_min = obj_diff;
924 bool Solver::be_shrunk(
int i,
double Gmax1,
double Gmax2)
926 if(is_upper_bound(i))
929 return(-G[i] > Gmax1);
931 return(-G[i] > Gmax2);
933 else if(is_lower_bound(i))
936 return(G[i] > Gmax2);
938 return(G[i] > Gmax1);
944 void Solver::do_shrinking()
951 for(i=0;i<active_size;i++)
955 if(!is_upper_bound(i))
960 if(!is_lower_bound(i))
968 if(!is_upper_bound(i))
973 if(!is_lower_bound(i))
981 if(unshrink ==
false && Gmax1 + Gmax2 <=
eps*10)
984 reconstruct_gradient();
989 for(i=0;i<active_size;i++)
990 if (be_shrunk(i, Gmax1, Gmax2))
993 while (active_size > i)
995 if (!be_shrunk(active_size, Gmax1, Gmax2))
997 swap_index(i,active_size);
1005 double Solver::calculate_rho()
1009 double ub =
INF, lb = -
INF, sum_free = 0;
1010 for(
int i=0;i<active_size;i++)
1012 double yG = y[i]*G[i];
1014 if(is_upper_bound(i))
1021 else if(is_lower_bound(i))
1036 r = sum_free/nr_free;
1048 class Solver_NU:
public Solver
1052 void Solve(
int l,
const QMatrix& Q,
const double *p,
const schar *y,
1053 double *alpha,
double* C_,
double eps,
1054 SolutionInfo* si,
int shrinking)
1057 Solver::Solve(l,Q,p,y,alpha,C_,eps,si,shrinking);
1061 int select_working_set(
int &i,
int &j)
override;
1062 double calculate_rho()
override;
1063 bool be_shrunk(
int i,
double Gmax1,
double Gmax2,
double Gmax3,
double Gmax4);
1064 void do_shrinking()
override;
1068 int Solver_NU::select_working_set(
int &out_i,
int &out_j)
1076 double Gmaxp = -
INF;
1077 double Gmaxp2 = -
INF;
1080 double Gmaxn = -
INF;
1081 double Gmaxn2 = -
INF;
1085 double obj_diff_min =
INF;
1087 for(
int t=0;t<active_size;t++)
1090 if(!is_upper_bound(t))
1099 if(!is_lower_bound(t))
1109 const Qfloat *Q_ip =
nullptr;
1110 const Qfloat *Q_in =
nullptr;
1112 Q_ip = Q->get_Q(ip,active_size);
1114 Q_in = Q->get_Q(in,active_size);
1116 for(
int j=0;j<active_size;j++)
1120 if (!is_lower_bound(j))
1122 double grad_diff=Gmaxp+G[j];
1128 double quad_coef = QD[ip]+QD[j]-2*Q_ip[j];
1130 obj_diff = -(grad_diff*grad_diff)/quad_coef;
1132 obj_diff = -(grad_diff*grad_diff)/
TAU;
1134 if (obj_diff <= obj_diff_min)
1137 obj_diff_min = obj_diff;
1144 if (!is_upper_bound(j))
1146 double grad_diff=Gmaxn-G[j];
1147 if (-G[j] >= Gmaxn2)
1152 double quad_coef = QD[
in]+QD[j]-2*Q_in[j];
1154 obj_diff = -(grad_diff*grad_diff)/quad_coef;
1156 obj_diff = -(grad_diff*grad_diff)/
TAU;
1158 if (obj_diff <= obj_diff_min)
1161 obj_diff_min = obj_diff;
1168 if(
max(Gmaxp+Gmaxp2,Gmaxn+Gmaxn2) <
eps)
1171 if (y[Gmin_idx] == +1)
1180 bool Solver_NU::be_shrunk(
int i,
double Gmax1,
double Gmax2,
double Gmax3,
double Gmax4)
1182 if(is_upper_bound(i))
1185 return(-G[i] > Gmax1);
1187 return(-G[i] > Gmax4);
1189 else if(is_lower_bound(i))
1192 return(G[i] > Gmax2);
1194 return(G[i] > Gmax3);
1200 void Solver_NU::do_shrinking()
1202 double Gmax1 = -
INF;
1203 double Gmax2 = -
INF;
1204 double Gmax3 = -
INF;
1205 double Gmax4 = -
INF;
1209 for(i=0;i<active_size;i++)
1211 if(!is_upper_bound(i))
1215 if(-G[i] > Gmax1) Gmax1 = -G[i];
1217 else if(-G[i] > Gmax4) Gmax4 = -G[i];
1219 if(!is_lower_bound(i))
1223 if(G[i] > Gmax2) Gmax2 = G[i];
1225 else if(G[i] > Gmax3) Gmax3 = G[i];
1229 if(unshrink ==
false &&
max(Gmax1+Gmax2,Gmax3+Gmax4) <=
eps*10)
1232 reconstruct_gradient();
1236 for(i=0;i<active_size;i++)
1237 if (be_shrunk(i, Gmax1, Gmax2, Gmax3, Gmax4))
1240 while (active_size > i)
1242 if (!be_shrunk(active_size, Gmax1, Gmax2, Gmax3, Gmax4))
1244 swap_index(i,active_size);
1252 double Solver_NU::calculate_rho()
1254 int nr_free1 = 0,nr_free2 = 0;
1255 double ub1 =
INF, ub2 =
INF;
1256 double lb1 = -
INF, lb2 = -
INF;
1257 double sum_free1 = 0, sum_free2 = 0;
1259 for(
int i=0;i<active_size;i++)
1263 if(is_upper_bound(i))
1264 lb1 =
max(lb1,G[i]);
1265 else if(is_lower_bound(i))
1266 ub1 =
min(ub1,G[i]);
1275 if(is_upper_bound(i))
1276 lb2 =
max(lb2,G[i]);
1277 else if(is_lower_bound(i))
1278 ub2 =
min(ub2,G[i]);
1289 r1 = sum_free1/nr_free1;
1294 r2 = sum_free2/nr_free2;
1305 class SVC_Q:
public Kernel
1309 :Kernel(prob.
l, prob.
x, param)
1312 cache =
new Cache(prob.
l,(
long int)(param.
cache_size*(1<<20)));
1313 QD =
new double[prob.
l];
1314 for(
int i=0;i<prob.
l;i++)
1315 QD[i] = (this->*kernel_function)(i,i);
1318 Qfloat *get_Q(
int i,
int len)
const override 1322 if((start = cache->get_data(i,&data,len)) < len)
1324 for(j=start;j<len;j++)
1325 data[j] = (
Qfloat)(y[i]*y[j]*(this->*kernel_function)(i,j));
1330 double *get_QD()
const override 1335 void swap_index(
int i,
int j)
const override 1337 cache->swap_index(i,j);
1338 Kernel::swap_index(i,j);
1355 class ONE_CLASS_Q:
public Kernel
1359 :Kernel(prob.
l, prob.
x, param)
1361 cache =
new Cache(prob.
l,(
long int)(param.
cache_size*(1<<20)));
1362 QD =
new double[prob.
l];
1363 for(
int i=0;i<prob.
l;i++)
1364 QD[i] = (this->*kernel_function)(i,i);
1367 Qfloat *get_Q(
int i,
int len)
const override 1371 if((start = cache->get_data(i,&data,len)) < len)
1373 for(j=start;j<len;j++)
1374 data[j] = (
Qfloat)(this->*kernel_function)(i,j);
1379 double *get_QD()
const override 1384 void swap_index(
int i,
int j)
const override 1386 cache->swap_index(i,j);
1387 Kernel::swap_index(i,j);
1391 ~ONE_CLASS_Q()
override 1401 class SVR_Q:
public Kernel
1405 :Kernel(prob.
l, prob.
x, param)
1408 cache =
new Cache(l,(
long int)(param.
cache_size*(1<<20)));
1409 QD =
new double[2*l];
1410 sign =
new schar[2*l];
1411 index =
new int[2*l];
1412 for(
int k=0;
k<l;
k++)
1418 QD[
k] = (this->*kernel_function)(
k,
k);
1421 buffer[0] =
new Qfloat[2*l];
1422 buffer[1] =
new Qfloat[2*l];
1426 void swap_index(
int i,
int j)
const override 1428 swap(sign[i],sign[j]);
1429 swap(index[i],index[j]);
1433 Qfloat *get_Q(
int i,
int len)
const override 1436 int j, real_i = index[i];
1437 if(cache->get_data(real_i,&data,l) < l)
1440 data[j] = (
Qfloat)(this->*kernel_function)(real_i,j);
1444 Qfloat *buf = buffer[next_buffer];
1445 next_buffer = 1 - next_buffer;
1448 buf[j] = (
Qfloat) si * (
Qfloat) sign[j] * data[index[j]];
1452 double *get_QD()
const override 1471 mutable int next_buffer;
1481 double *alpha, Solver::SolutionInfo* si,
double Cp,
double Cn)
1484 auto *minus_ones =
new double[l];
1485 auto *y =
new schar[l];
1486 auto *C =
new double[l];
1497 C[i] = prob->
W[i]*Cp;
1502 C[i] = prob->
W[i]*Cn;
1507 s.Solve(l, SVC_Q(*prob,*param,y), minus_ones, y,
1522 delete[] minus_ones;
1528 double *alpha, Solver::SolutionInfo* si)
1532 double nu = param->
nu;
1534 auto *y =
new schar[l];
1535 auto *C =
new double[l];
1547 for(i=0;i<l;i++) nu_l += nu*C[i];
1548 double sum_pos = nu_l/2;
1549 double sum_neg = nu_l/2;
1554 alpha[i] =
min(C[i],sum_pos);
1555 sum_pos -= alpha[i];
1559 alpha[i] =
min(C[i],sum_neg);
1560 sum_neg -= alpha[i];
1563 auto *zeros =
new double[l];
1569 s.Solve(l, SVC_Q(*prob,*param,y), zeros, y,
1573 info(
"C = %f\n",1/r);
1578 si->upper_bound[i] /= r;
1591 double *alpha, Solver::SolutionInfo* si)
1594 auto *zeros =
new double[l];
1595 auto *ones =
new schar[l];
1596 auto *C =
new double[l];
1604 nu_l += C[i] * param->
nu;
1610 alpha[i] =
min(C[i],nu_l);
1624 s.Solve(l, ONE_CLASS_Q(*prob,*param), zeros, ones,
1634 double *alpha, Solver::SolutionInfo* si)
1637 auto *alpha2 =
new double[2*l];
1638 auto *linear_term =
new double[2*l];
1639 auto *C =
new double[2*l];
1640 auto *y =
new schar[2*l];
1646 linear_term[i] = param->
p - prob->
y[i];
1648 C[i] = prob->
W[i]*param->
C;
1651 linear_term[i+l] = param->
p + prob->
y[i];
1653 C[i+l] = prob->
W[i]*param->
C;
1657 s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y,
1659 double sum_alpha = 0;
1662 alpha[i] = alpha2[i] - alpha2[i+l];
1663 sum_alpha += fabs(alpha[i]);
1667 delete[] linear_term;
1674 double *alpha, Solver::SolutionInfo* si)
1677 auto *C =
new double[2*l];
1678 auto *alpha2 =
new double[2*l];
1679 auto *linear_term =
new double[2*l];
1680 auto *y =
new schar[2*l];
1686 C[i] = C[i+l] = prob->
W[i]*param->
C;
1687 sum += C[i] * param->
nu;
1693 alpha2[i] = alpha2[i+l] =
min(sum,C[i]);
1696 linear_term[i] = - prob->
y[i];
1699 linear_term[i+l] = prob->
y[i];
1704 s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y,
1707 info(
"epsilon = %f\n",-si->r);
1710 alpha[i] = alpha2[i] - alpha2[i+l];
1713 delete[] linear_term;
1721 struct decision_function
1729 double Cp,
double Cn)
1731 auto *alpha =
Malloc(
double,prob->
l);
1732 Solver::SolutionInfo si;
1736 si.upper_bound =
Malloc(
double,prob->
l);
1740 si.upper_bound =
Malloc(
double,prob->
l);
1744 si.upper_bound =
Malloc(
double,prob->
l);
1748 si.upper_bound =
Malloc(
double,2*prob->
l);
1752 si.upper_bound =
Malloc(
double,2*prob->
l);
1757 info(
"obj = %f, rho = %f\n",si.obj,si.rho);
1763 for(
int i=0;i<prob->
l;i++)
1765 if(fabs(alpha[i]) > 0)
1770 if(fabs(alpha[i]) >= si.upper_bound[i])
1775 if(fabs(alpha[i]) >= si.upper_bound[i])
1781 free(si.upper_bound);
1783 info(
"nSV = %d, nBSV = %d\n",nSV,nBSV);
1785 decision_function f;
1793 int l,
const double *dec_values,
const double *labels,
1794 double& A,
double& B)
1796 double prior1=0, prior0 = 0;
1800 if (labels[i] > 0) prior1+=1;
1804 double min_step=1e-10;
1807 double hiTarget=(prior1+1.0)/(prior1+2.0);
1808 double loTarget=1/(prior0+2.0);
1809 auto *t=
Malloc(
double,l);
1810 double fApB,p,q,h11,h22,h21,g1,g2,det,dA,dB,gd,stepsize;
1811 double newA,newB,newf,d1,d2;
1815 A=0.0; B=log((prior0+1.0)/(prior1+1.0));
1820 if (labels[i]>0) t[i]=hiTarget;
1822 fApB = dec_values[i]*A+B;
1824 fval += t[i]*fApB + log(1+exp(-fApB));
1826 fval += (t[i] - 1)*fApB +log(1+exp(fApB));
1828 for (iter=0;iter<max_iter;iter++)
1833 h21=0.0;g1=0.0;g2=0.0;
1836 fApB = dec_values[i]*A+B;
1839 p=exp(-fApB)/(1.0+exp(-fApB));
1840 q=1.0/(1.0+exp(-fApB));
1844 p=1.0/(1.0+exp(fApB));
1845 q=exp(fApB)/(1.0+exp(fApB));
1848 h11+=dec_values[i]*dec_values[i]*d2;
1850 h21+=dec_values[i]*d2;
1852 g1+=dec_values[i]*d1;
1857 if (fabs(g1)<eps && fabs(g2)<
eps)
1861 det=h11*h22-h21*h21;
1862 dA=-(h22*g1 - h21 * g2) / det;
1863 dB=-(-h21*g1+ h11 * g2) / det;
1868 while (stepsize >= min_step)
1870 newA = A + stepsize * dA;
1871 newB = B + stepsize * dB;
1877 fApB = dec_values[i]*newA+newB;
1879 newf += t[i]*fApB + log(1+exp(-fApB));
1881 newf += (t[i] - 1)*fApB +log(1+exp(fApB));
1884 if (newf<fval+0.0001*stepsize*gd)
1886 A=newA;B=newB;fval=newf;
1890 stepsize = stepsize / 2.0;
1893 if (stepsize < min_step)
1895 info(
"Line search fails in two-class probability estimates\n");
1901 info(
"Reaching maximal iterations in two-class probability estimates\n");
1907 double fApB = decision_value*A+B;
1910 return exp(-fApB)/(1.0+exp(-fApB));
1912 return 1.0/(1+exp(fApB)) ;
1919 int iter = 0, max_iter=
max(100,k);
1920 auto **Q=
Malloc(
double *,k);
1921 auto *Qp=
Malloc(
double,k);
1922 double pQp,
eps=0.005/
k;
1931 Q[t][t]+=r[j][t]*r[j][t];
1936 Q[t][t]+=r[j][t]*r[j][t];
1937 Q[t][j]=-r[j][t]*r[t][j];
1940 for (iter=0;iter<max_iter;iter++)
1948 Qp[t]+=Q[t][j]*p[j];
1954 double error=fabs(Qp[t]-pQp);
1955 if (error>max_error)
1958 if (max_error<eps)
break;
1962 double diff=(-Qp[t]+pQp)/Q[t][t];
1964 pQp=(pQp+diff*(diff*Q[t][t]+2*Qp[t]))/(1+diff)/(1+diff);
1967 Qp[j]=(Qp[j]+diff*Q[t][j])/(1+diff);
1973 info(
"Exceeds max_iter in multiclass_prob\n");
1974 for(t=0;t<
k;t++) free(Q[t]);
1982 double Cp,
double Cn,
double& probA,
double& probB)
1986 auto *perm =
Malloc(
int,prob->
l);
1987 auto *dec_values =
Malloc(
double,prob->
l);
1990 for(i=0;i<prob->
l;i++) perm[i]=i;
1991 for(i=0;i<prob->
l;i++)
1993 int j = i+rand()%(prob->
l-i);
1994 swap(perm[i],perm[j]);
1996 for(i=0;i<nr_fold;i++)
1998 int begin = i*prob->
l/nr_fold;
1999 int end = (i+1)*prob->
l/nr_fold;
2003 subprob.
l = prob->
l-(end-begin);
2005 subprob.y =
Malloc(
double,subprob.l);
2006 subprob.W =
Malloc(
double,subprob.l);
2009 for(j=0;j<begin;j++)
2011 subprob.x[
k] = prob->
x[perm[j]];
2012 subprob.y[
k] = prob->
y[perm[j]];
2013 subprob.W[
k] = prob->
W[perm[j]];
2016 for(j=end;j<prob->
l;j++)
2018 subprob.x[
k] = prob->
x[perm[j]];
2019 subprob.y[
k] = prob->
y[perm[j]];
2020 subprob.W[
k] = prob->
W[perm[j]];
2023 int p_count=0,n_count=0;
2030 if(p_count==0 && n_count==0)
2031 for(j=begin;j<end;j++)
2032 dec_values[perm[j]] = 0;
2033 else if(p_count > 0 && n_count == 0)
2034 for(j=begin;j<end;j++)
2035 dec_values[perm[j]] = 1;
2036 else if(p_count == 0 && n_count > 0)
2037 for(j=begin;j<end;j++)
2038 dec_values[perm[j]] = -1;
2052 for(j=begin;j<end;j++)
2056 dec_values[perm[j]] *= submodel->
label[0];
2076 auto *ymv =
Malloc(
double,prob->
l);
2082 for(i=0;i<prob->
l;i++)
2084 ymv[i]=prob->
y[i]-ymv[i];
2085 mae += fabs(ymv[i]);
2088 double std=sqrt(2*mae*mae);
2091 for(i=0;i<prob->
l;i++)
2092 if (fabs(ymv[i]) > 5*std)
2096 mae /= (prob->
l-count);
2097 info(
"Prob. model for test data: target value = predicted value + z,\nz: Laplace distribution e^(-|z|/sigma)/(2sigma),sigma= %g\n",mae);
2108 int max_nr_class = 16;
2111 auto *count =
Malloc(
int,max_nr_class);
2112 auto *data_label =
Malloc(
int,l);
2117 auto this_label = (int)prob->
y[i];
2119 for(j=0;j<nr_class;j++)
2121 if(this_label ==
label[j])
2130 if(nr_class == max_nr_class)
2133 label = (
int *)realloc(
label,max_nr_class*
sizeof(
int));
2134 count = (
int *)realloc(count,max_nr_class*
sizeof(
int));
2147 if (nr_class == 2 &&
label[0] == -1 &&
label[1] == 1)
2150 swap(count[0],count[1]);
2153 if(data_label[i] == 0)
2160 auto *start =
Malloc(
int,nr_class);
2163 start[i] = start[i-1]+count[i-1];
2166 perm[start[data_label[i]]] = i;
2167 ++start[data_label[i]];
2171 start[i] = start[i-1]+count[i-1];
2187 for(i=0;i<prob->
l;i++)
2188 if(prob->
W[i] > 0) l++;
2192 newprob->
y =
Malloc(
double,l);
2193 newprob->
W =
Malloc(
double,l);
2196 for(i=0;i<prob->
l;i++)
2199 newprob->
x[j] = prob->
x[i];
2200 newprob->
y[j] = prob->
y[i];
2201 newprob->
W[j] = prob->
W[i];
2216 model->param = *
param;
2224 model->nr_class = 2;
2225 model->label =
nullptr;
2226 model->nSV =
nullptr;
2227 model->probA =
nullptr; model->probB =
nullptr;
2228 model->sv_coef =
Malloc(
double *,1);
2234 model->probA =
Malloc(
double,1);
2239 model->rho =
Malloc(
double,1);
2240 model->rho[0] = f.rho;
2244 for(i=0;i<prob->
l;i++)
2245 if(fabs(f.alpha[i]) > 0) ++
nSV;
2248 model->sv_coef[0] =
Malloc(
double,nSV);
2249 model->sv_indices =
Malloc(
int,nSV);
2251 for(i=0;i<prob->
l;i++)
2252 if(fabs(f.alpha[i]) > 0)
2254 model->SV[j] = prob->
x[i];
2255 model->sv_coef[0][j] = f.alpha[i];
2256 model->sv_indices[j] = i+1;
2267 int *
label =
nullptr;
2268 int *start =
nullptr;
2269 int *count =
nullptr;
2270 auto *perm =
Malloc(
int,l);
2275 info(
"WARNING: training data in only one class. See README for details.\n");
2284 x[i] = prob->
x[perm[i]];
2285 W[i] = prob->
W[perm[i]];
2290 auto *weighted_C =
Malloc(
double, nr_class);
2292 weighted_C[i] = param->
C;
2293 for(i=0;i<param->nr_weight;i++)
2300 fprintf(stderr,
"WARNING: class label %d specified in weight is not found\n", param->
weight_label[i]);
2302 weighted_C[j] *= param->
weight[i];
2307 auto *nonzero =
Malloc(
bool,l);
2310 auto *f =
Malloc(decision_function,nr_class*(nr_class-1)/2);
2315 probA=
Malloc(
double,nr_class*(nr_class-1)/2);
2324 int si = start[i], sj = start[j];
2325 int ci = count[i], cj = count[j];
2328 sub_prob.
y =
Malloc(
double,sub_prob.
l);
2329 sub_prob.
W =
Malloc(
double,sub_prob.
l);
2333 sub_prob.
x[
k] = x[si+
k];
2335 sub_prob.
W[
k] = W[si+
k];
2339 sub_prob.
x[ci+
k] = x[sj+
k];
2340 sub_prob.
y[ci+
k] = -1;
2341 sub_prob.
W[ci+
k] = W[sj+
k];
2347 f[p] =
svm_train_one(&sub_prob,param,weighted_C[i],weighted_C[j]);
2349 if(!nonzero[si+k] && fabs(f[p].alpha[k]) > 0)
2350 nonzero[si+
k] =
true;
2352 if(!nonzero[sj+k] && fabs(f[p].alpha[ci+k]) > 0)
2353 nonzero[sj+
k] =
true;
2364 model->label =
Malloc(
int,nr_class);
2366 model->label[i] = label[i];
2368 model->rho =
Malloc(
double,nr_class*(nr_class-1)/2);
2369 for(i=0;i<nr_class*(nr_class-1)/2;i++)
2370 model->rho[i] = f[i].rho;
2374 model->probA =
Malloc(
double,nr_class*(nr_class-1)/2);
2375 model->probB =
Malloc(
double,nr_class*(nr_class-1)/2);
2376 for(i=0;i<nr_class*(nr_class-1)/2;i++)
2378 model->probA[i] = probA[i];
2379 model->probB[i] =
probB[i];
2384 model->probA=
nullptr;
2385 model->probB=
nullptr;
2389 auto *nz_count =
Malloc(
int,nr_class);
2390 model->nSV =
Malloc(
int,nr_class);
2394 for(
int j=0;j<count[i];j++)
2395 if(nonzero[start[i]+j])
2400 model->nSV[i] =
nSV;
2404 info(
"Total nSV = %d\n",total_sv);
2406 model->l = total_sv;
2408 model->sv_indices =
Malloc(
int,total_sv);
2413 model->SV[p] = x[i];
2414 model->sv_indices[p++] = perm[i] + 1;
2417 auto *nz_start =
Malloc(
int,nr_class);
2420 nz_start[i] = nz_start[i-1]+nz_count[i-1];
2422 model->sv_coef =
Malloc(
double *,nr_class-1);
2423 for(i=0;i<nr_class-1;i++)
2424 model->sv_coef[i] =
Malloc(
double,total_sv);
2439 int q = nz_start[i];
2443 model->sv_coef[j-1][q++] = f[p].alpha[
k];
2447 model->sv_coef[i][q++] = f[p].alpha[ci+
k];
2461 for(i=0;i<nr_class*(nr_class-1)/2;i++)
2479 auto *perm =
Malloc(
int,l);
2484 fprintf(stderr,
"WARNING: # folds > # data. Will use # folds = # data instead (i.e., leave-one-out cross validation)\n");
2486 fold_start =
Malloc(
int,nr_fold+1);
2492 int *start =
nullptr;
2493 int *
label =
nullptr;
2494 int *count =
nullptr;
2498 auto *fold_count =
Malloc(
int,nr_fold);
2500 auto *index =
Malloc(
int,l);
2504 for(i=0;i<count[c];i++)
2506 int j = i+rand()%(count[c]-i);
2507 swap(index[start[c]+j],index[start[c]+i]);
2509 for(i=0;i<nr_fold;i++)
2513 fold_count[i]+=(i+1)*count[c]/nr_fold-i*count[c]/nr_fold;
2516 for (i=1;i<=nr_fold;i++)
2517 fold_start[i] = fold_start[i-1]+fold_count[i-1];
2519 for(i=0;i<nr_fold;i++)
2521 int begin = start[c]+i*count[c]/nr_fold;
2522 int end = start[c]+(i+1)*count[c]/nr_fold;
2523 for(
int j=begin;j<end;j++)
2525 perm[fold_start[i]] = index[j];
2530 for (i=1;i<=nr_fold;i++)
2531 fold_start[i] = fold_start[i-1]+fold_count[i-1];
2540 for(i=0;i<
l;i++) perm[i]=i;
2543 int j = i+rand()%(l-i);
2544 swap(perm[i],perm[j]);
2546 for(i=0;i<=nr_fold;i++)
2547 fold_start[i]=i*l/nr_fold;
2550 for(i=0;i<nr_fold;i++)
2552 int begin = fold_start[i];
2553 int end = fold_start[i+1];
2557 subprob.
l = l-(end-begin);
2559 subprob.
y =
Malloc(
double,subprob.
l);
2561 subprob.
W =
Malloc(
double,subprob.
l);
2563 for(j=0;j<begin;j++)
2565 subprob.
x[
k] = prob->
x[perm[j]];
2566 subprob.
y[
k] = prob->
y[perm[j]];
2567 subprob.
W[
k] = prob->
W[perm[j]];
2572 subprob.
x[
k] = prob->
x[perm[j]];
2573 subprob.
y[
k] = prob->
y[perm[j]];
2574 subprob.
W[
k] = prob->
W[perm[j]];
2582 for(j=begin;j<end;j++)
2584 free(prob_estimates);
2587 for(j=begin;j<end;j++)
2588 target[perm[j]] =
svm_predict(submodel,prob->
x[perm[j]]);
2611 if (model->
label !=
nullptr)
2613 label[i] = model->
label[i];
2619 for(
int i=0;i<model->
l;i++)
2631 model->
probA!=
nullptr)
2632 return model->
probA[0];
2635 fprintf(stderr,
"Model doesn't contain information for SVR probability inference\n");
2649 for(i=0;i<model->
l;i++)
2650 sum += sv_coef[i] * Kernel::k_function(x,model->
SV[i],model->
param);
2651 sum -= model->
rho[0];
2655 return (sum>0)?1:-1;
2664 auto *kvalue =
Malloc(
double,l);
2666 kvalue[i] = Kernel::k_function(x,model->
SV[i],model->
param);
2668 auto *start =
Malloc(
int,nr_class);
2671 start[i] = start[i-1]+model->
nSV[i-1];
2673 auto *vote =
Malloc(
int,nr_class);
2684 int ci = model->
nSV[i];
2685 int cj = model->
nSV[j];
2688 double *coef1 = model->
sv_coef[j-1];
2689 double *coef2 = model->
sv_coef[i];
2691 sum += coef1[si+k] * kvalue[si+k];
2693 sum += coef2[sj+k] * kvalue[sj+k];
2694 sum -= model->
rho[p];
2695 dec_values[p] = sum;
2697 if(dec_values[p] > 0)
2704 int vote_max_idx = 0;
2706 if(vote[i] > vote[vote_max_idx])
2712 return model->
label[vote_max_idx];
2723 dec_values =
Malloc(
double, 1);
2725 dec_values =
Malloc(
double, nr_class*(nr_class-1)/2);
2735 model->
probA!=
nullptr && model->
probB!=
nullptr)
2739 auto *dec_values =
Malloc(
double, nr_class*(nr_class-1)/2);
2742 double min_prob=1e-7;
2743 auto **pairwise_prob=
Malloc(
double *,nr_class);
2745 pairwise_prob[i]=
Malloc(
double,nr_class);
2751 pairwise_prob[j][i]=1-pairwise_prob[i][j];
2756 int prob_max_idx = 0;
2758 if(prob_estimates[i] > prob_estimates[prob_max_idx])
2761 free(pairwise_prob[i]);
2763 free(pairwise_prob);
2764 return model->
label[prob_max_idx];
2772 "c_svc",
"nu_svc",
"one_class",
"epsilon_svr",
"nu_svr",
nullptr 2777 "linear",
"polynomial",
"rbf",
"sigmoid",
"precomputed",
nullptr 2782 FILE *fp = fopen(model_file_name,
"w");
2783 if(fp==
nullptr)
return -1;
2793 fprintf(fp,
"degree %d\n", param.
degree);
2796 fprintf(fp,
"gamma %g\n", param.
gamma);
2799 fprintf(fp,
"coef0 %g\n", param.
coef0);
2803 fprintf(fp,
"nr_class %d\n", nr_class);
2804 fprintf(fp,
"total_sv %d\n",l);
2808 for(
int i=0;i<nr_class*(nr_class-1)/2;i++)
2809 fprintf(fp,
" %g",model->
rho[i]);
2815 fprintf(fp,
"label");
2817 fprintf(fp,
" %d",model->
label[i]);
2823 fprintf(fp,
"probA");
2824 for(
int i=0;i<nr_class*(nr_class-1)/2;i++)
2825 fprintf(fp,
" %g",model->
probA[i]);
2830 fprintf(fp,
"probB");
2831 for(
int i=0;i<nr_class*(nr_class-1)/2;i++)
2832 fprintf(fp,
" %g",model->
probB[i]);
2838 fprintf(fp,
"nr_sv");
2840 fprintf(fp,
" %d",model->
nSV[i]);
2844 fprintf(fp,
"SV\n");
2848 for(
int i=0;i<
l;i++)
2850 for(
int j=0;j<nr_class-1;j++)
2851 fprintf(fp,
"%.16g ",sv_coef[j][i]);
2856 fprintf(fp,
"0:%d ",(
int)(p->
value));
2858 while(p->
index != -1)
2866 if (ferror(fp) != 0 || fclose(fp) != 0)
return -1;
2880 while(strrchr(
line,
'\n') ==
nullptr)
2884 len = (int) strlen(
line);
2898 #define FSCANF(_stream, _format, _var) do{ if (fscanf(_stream, _format, _var) != 1) return false; }while(0) 2907 if(strcmp(cmd,
"svm_type")==0)
2921 fprintf(stderr,
"unknown svm type.\n");
2925 else if(strcmp(cmd,
"kernel_type")==0)
2939 fprintf(stderr,
"unknown kernel function.\n");
2943 else if(strcmp(cmd,
"degree")==0)
2945 else if(strcmp(cmd,
"gamma")==0)
2947 else if(strcmp(cmd,
"coef0")==0)
2949 else if(strcmp(cmd,
"nr_class")==0)
2951 else if(strcmp(cmd,
"total_sv")==0)
2953 else if(strcmp(cmd,
"rho")==0)
2957 for(
int i=0;i<n;i++)
2960 else if(strcmp(cmd,
"label")==0)
2964 for(
int i=0;i<n;i++)
2967 else if(strcmp(cmd,
"probA")==0)
2971 for(
int i=0;i<n;i++)
2974 else if(strcmp(cmd,
"probB")==0)
2978 for(
int i=0;i<n;i++)
2981 else if(strcmp(cmd,
"nr_sv")==0)
2985 for(
int i=0;i<n;i++)
2988 else if(strcmp(cmd,
"SV")==0)
2993 if(c==EOF || c==
'\n')
break;
2999 fprintf(stderr,
"unknown text in model file: [%s]\n",cmd);
3010 FILE *fp = fopen(model_file_name,
"rb");
3011 if(fp==
nullptr)
return nullptr;
3018 model->rho =
nullptr;
3019 model->probA =
nullptr;
3020 model->probB =
nullptr;
3021 model->sv_indices =
nullptr;
3022 model->label =
nullptr;
3023 model->nSV =
nullptr;
3028 fprintf(stderr,
"ERROR: fscanf failed to read model\n");
3039 long pos = ftell(fp);
3043 char *p,*endptr,*idx,*val;
3047 p = strtok(
line,
":");
3050 p = strtok(
nullptr,
":");
3056 elements += model->l;
3058 fseek(fp,pos,SEEK_SET);
3060 int m = model->nr_class - 1;
3062 model->sv_coef =
Malloc(
double *,m);
3065 model->sv_coef[i] =
Malloc(
double,l);
3074 model->SV[i] = &x_space[j];
3076 p = strtok(
line,
" \t");
3077 model->sv_coef[0][i] = strtod(p,&endptr);
3078 for(
int k=1;
k<m;
k++)
3080 p = strtok(
nullptr,
" \t");
3081 model->sv_coef[
k][i] = strtod(p,&endptr);
3086 idx = strtok(
nullptr,
":");
3087 val = strtok(
nullptr,
" \t");
3091 x_space[j].
index = (int) strtol(idx,&endptr,10);
3092 x_space[j].
value = strtod(val,&endptr);
3096 x_space[j++].
index = -1;
3100 if (ferror(fp) != 0 || fclose(fp) != 0)
3109 if(model_ptr->
free_sv && model_ptr->
l > 0 && model_ptr->
SV !=
nullptr)
3110 free((
void *)(model_ptr->
SV[0]));
3113 for(
int i=0;i<model_ptr->
nr_class-1;i++)
3117 free(model_ptr->
SV);
3118 model_ptr->
SV =
nullptr;
3123 free(model_ptr->
rho);
3124 model_ptr->
rho =
nullptr;
3126 free(model_ptr->
label);
3127 model_ptr->
label=
nullptr;
3129 free(model_ptr->
probA);
3130 model_ptr->
probA =
nullptr;
3132 free(model_ptr->
probB);
3133 model_ptr->
probB=
nullptr;
3138 free(model_ptr->
nSV);
3139 model_ptr->
nSV =
nullptr;
3144 if(model_ptr_ptr !=
nullptr && *model_ptr_ptr !=
nullptr)
3147 free(*model_ptr_ptr);
3148 *model_ptr_ptr =
nullptr;
3163 if(svm_type !=
C_SVC &&
3168 return "unknown svm type";
3173 if(kernel_type !=
LINEAR &&
3174 kernel_type !=
POLY &&
3175 kernel_type !=
RBF &&
3178 return "unknown kernel type";
3180 if(param->
gamma < 0)
3184 return "degree of polynomial kernel < 0";
3189 return "cache_size <= 0";
3194 if(svm_type ==
C_SVC ||
3203 if(param->
nu <= 0 || param->
nu > 1)
3204 return "nu <= 0 or nu > 1";
3212 return "shrinking != 0 and shrinking != 1";
3216 return "probability != 0 and probability != 1";
3220 return "one-class SVM probability output not supported yet";
3228 int max_nr_class = 16;
3231 auto *count =
Malloc(
double,max_nr_class);
3236 auto this_label = (int)prob->
y[i];
3238 for(j=0;j<nr_class;j++)
3239 if(this_label ==
label[j])
3241 count[j] += prob->
W[i];
3246 if(nr_class == max_nr_class)
3249 label = (
int *)realloc(
label,max_nr_class*
sizeof(
int));
3250 count = (
double *)realloc(count,max_nr_class*
sizeof(
double));
3260 double n1 = count[i];
3263 double n2 = count[j];
3264 if(param->
nu*(n1+n2)/2 >
min(n1,n2))
3268 return "specified nu is infeasible";
3282 model->
probA!=
nullptr && model->
probB!=
nullptr) ||
3284 model->
probA!=
nullptr);
3289 if(print_func ==
nullptr)
int svm_save_model(const char *model_file_name, const svm_model *model)
svm_model * svm_train(const svm_problem *prob, const svm_parameter *param)
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 void solve_one_class(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si)
void svm_free_model_content(svm_model *model_ptr)
const char * svm_check_parameter(const svm_problem *prob, const svm_parameter *param)
static double sigmoid_predict(double decision_value, double A, double B)
static void solve_epsilon_svr(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si)
int svm_get_nr_sv(const svm_model *model)
static const char * kernel_type_table[]
void svm_cross_validation(const svm_problem *prob, const svm_parameter *param, int nr_fold, double *target)
static void sigmoid_train(int l, const double *dec_values, const double *labels, double &A, double &B)
double svm_get_svr_probability(const svm_model *model)
double svm_predict(const svm_model *model, const svm_node *x)
static void info(const char *fmt,...)
static void print_string_stdout(const char *s)
int svm_get_nr_class(const svm_model *model)
int svm_check_probability_model(const svm_model *model)
static void solve_nu_svr(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si)
Convenience class to temporarily change the current locale.
static void clone(T *&dst, S *src, int n)
static void(* svm_print_string)(const char *)
static void svm_binary_svc_probability(const svm_problem *prob, const svm_parameter *param, double Cp, double Cn, double &probA, double &probB)
static char * readline(FILE *input)
bool read_model_header(FILE *fp, svm_model *model)
static double powi(double base, int times)
void svm_free_and_destroy_model(svm_model **model_ptr_ptr)
double svm_predict_values(const svm_model *model, const svm_node *x, double *dec_values)
double svm_predict_probability(const svm_model *model, const svm_node *x, double *prob_estimates)
struct svm_parameter param
static double svm_svr_probability(const svm_problem *prob, const svm_parameter *param)
void svm_get_sv_indices(const svm_model *model, int *indices)
#define FSCANF(_stream, _format, _var)
static bool in(Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4)
static decision_function svm_train_one(const svm_problem *prob, const svm_parameter *param, double Cp, double Cn)
static void multiclass_probability(int k, double **r, double *p)
static void swap(T &x, T &y)
int svm_get_svm_type(const svm_model *model)
static void solve_nu_svc(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si)
MITKCORE_EXPORT const ScalarType eps
static const char * svm_type_table[]
static void solve_c_svc(const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo *si, double Cp, double Cn)
svm_model * svm_load_model(const char *model_file_name)
void svm_destroy_param(svm_parameter *param)
void svm_get_labels(const svm_model *model, int *label)
void svm_set_print_string_function(void(*print_func)(const char *))
static void remove_zero_weight(svm_problem *newprob, const svm_problem *prob)