SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CCSOSVM.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2012 Viktor Gal
8  * Copyright (C) 2008 Chun-Nam Yu
9  */
10 
13 
14 #ifdef USE_MOSEK
15 #include <mosek.h>
16 #endif
17 
18 using namespace shogun;
19 
22 {
23  init();
24 }
25 
27  : CLinearStructuredOutputMachine(model, model->get_labels())
28 {
29  init();
30 
31  if (w.vlen)
32  {
33  set_w(w);
34  }
35  else
36  {
38  m_w.zero();
39  }
40 }
41 
43 {
44 
45 }
46 
47 int32_t CCCSOSVM::mosek_qp_optimize(float64_t** G, float64_t* delta, float64_t* alpha, int32_t k, float64_t* dual_obj, float64_t rho)
48 {
49 #ifdef USE_MOSEK
50  int32_t t;
51  index_t Q_size = k*(k+1)/2;
53  MSKlidxt *aptrb;
54  MSKlidxt *aptre;
55  MSKidxt *asub;
56  SGVector<float64_t> aval(k);
57  MSKboundkeye bkc[1];
58  float64_t blc[1];
59  float64_t buc[1];
60  MSKboundkeye *bkx;
61  SGVector<float64_t> blx(k);
62  SGVector<float64_t> bux(k);
63  MSKidxt *qsubi,*qsubj;
64  SGVector<float64_t> qval(Q_size);
65 
66  MSKenv_t env;
67  MSKtask_t task;
68  MSKrescodee r;
69 
70  aptrb = (MSKlidxt*) SG_MALLOC(MSKlidxt, k);
71  aptre = (MSKlidxt*) SG_MALLOC(MSKlidxt, k);
72  asub = (MSKidxt*) SG_MALLOC(MSKidxt, k);
73  bkx = (MSKboundkeye*) SG_MALLOC(MSKboundkeye, k);
74  qsubi = (MSKidxt*) SG_MALLOC(MSKidxt, Q_size);
75  qsubj = (MSKidxt*) SG_MALLOC(MSKidxt, Q_size);
76 
77 
78  /* DEBUG */
79  /*
80  for (int32_t i=0;i<k;i++) {
81  printf("delta: %.4f\n", delta[i]);
82  }
83  printf("G:\n");
84  for (int32_t i=0;i<k;i++) {
85  for (int32_t j=0;j<k;j++) {
86  printf("%.4f ", G[i][j]);
87  }
88  printf("\n");
89  }
90  fflush(stdout);
91  */
92  /* DEBUG */
93 
94 
95  for (int32_t i=0; i < k;i++)
96  {
97  c[i] = -delta[i];
98  aptrb[i] = i;
99  aptre[i] = i+1;
100  asub[i] = 0;
101  aval[i] = 1.0;
102  bkx[i] = MSK_BK_LO;
103  blx[i] = 0.0;
104  bux[i] = MSK_INFINITY;
105  }
106  bkc[0] = MSK_BK_FX;
107  blc[0] = m_C;
108  buc[0] = m_C;
109 
110  /* create mosek environment */
111 #if (MSK_VERSION_MAJOR == 6)
112  r = MSK_makeenv(&env, NULL, NULL, NULL, NULL);
113 #elif (MSK_VERSION_MAJOR == 7)
114  r = MSK_makeenv(&env, NULL);
115 #else
116  #error "Unsupported Mosek version"
117 #endif
118 
119  /* check return code */
120  if (r==MSK_RES_OK)
121  {
122  /* directs output to printstr function */
123  // MSK_linkfunctoenvstream(env, MSK_STREAM_LOG, NULL, CMosek::print);
124  }
125 
126  /* initialize the environment */
127  r = MSK_initenv(env);
128 
129  if (r==MSK_RES_OK)
130  {
131  /* create the optimization task */
132  r = MSK_maketask(env,1,k,&task);
133 
134  if (r==MSK_RES_OK)
135  {
136  // r = MSK_linkfunctotaskstream(task, MSK_STREAM_LOG, NULL, CMosek::print);
137 
138  if (r==MSK_RES_OK)
139  {
140  r = MSK_inputdata(task,
141  1,k,
142  1,k,
143  c,0.0,
144  aptrb,aptre,
145  asub,aval,
146  bkc,blc,buc,
147  bkx,blx,bux);
148 
149  }
150 
151  if (r==MSK_RES_OK) {
152  /* coefficients for the Gram matrix */
153  t = 0;
154  for (int32_t i=0;i<k;i++) {
155  for (int32_t j=0;j<=i;j++) {
156  qsubi[t] = i;
157  qsubj[t] = j;
158  qval[t] = G[i][j]/(1+rho);
159  t++;
160  }
161  }
162 
163  r = MSK_putqobj(task, k*(k+1)/2, qsubi,qsubj,qval);
164  }
165 
166  /* DEBUG */
167  /*
168  printf("t: %ld\n", t);
169  for (int32_t i=0;i<t;i++) {
170  printf("qsubi: %d, qsubj: %d, qval: %.4f\n", qsubi[i], qsubj[i], qval[i]);
171  }
172  fflush(stdout);
173  */
174  /* DEBUG */
175 
176  /* set relative tolerance gap (DEFAULT = 1E-8)*/
177  MSK_putdouparam(task, MSK_DPAR_INTPNT_TOL_REL_GAP, 1E-14);
178 
179  if (r==MSK_RES_OK) {
180  r = MSK_optimize(task);
181  }
182 
183  if (r==MSK_RES_OK) {
184  MSK_getsolutionslice(task,
185  MSK_SOL_ITR,
186  MSK_SOL_ITEM_XX,
187  0,
188  k,
189  alpha);
190  /* output the objective value */
191  MSK_getprimalobj(task, MSK_SOL_ITR, dual_obj);
192  }
193  MSK_deletetask(&task);
194  }
195  MSK_deleteenv(&env);
196  }
197 
198  /* free the memory */
199  free(aptrb);
200  free(aptre);
201  free(asub);
202  free(bkx);
203  free(qsubi);
204  free(qsubj);
205 
206  return r;
207 #else
208  return -1;
209 #endif
210 }
211 
213 {
214  if (data)
215  set_features(data);
216 
217  SGVector<float64_t> alpha;
218  float64_t** G; /* Gram matrix */
219  DynArray<SGSparseVector<float64_t> > dXc; /* constraint matrix */
220  // DOC **dXc; /* constraint matrix */
221  SGVector<float64_t> delta; /* rhs of constraints */
222  SGSparseVector<float64_t> new_constraint;
223  float64_t dual_obj=0, alphasum;
224  int32_t iter, size_active;
225  float64_t value;
226  SGVector<int32_t> idle; /* for cleaning up */
227  float64_t margin;
228  float64_t primal_obj;
229  SGVector<float64_t> proximal_rhs;
230  SGVector<float64_t> gammaG0;
231  float64_t min_rho = 0.001;
232  float64_t serious_counter=0;
233  float64_t rho = 1.0; /* temporarily set it to 1 first */
234 
235  float64_t expected_descent, primal_obj_b=-1, reg_master_obj;
236  int32_t null_step=1;
237  float64_t kappa=0.1;
238  float64_t temp_var;
239  float64_t proximal_term, primal_lower_bound;
240 
241  float64_t v_k;
242  float64_t obj_difference;
243  SGVector<float64_t> cut_error; // cut_error[i] = alpha_{k,i} at current center x_k
244  float64_t sigma_k;
245  float64_t m2 = 0.2;
246  float64_t m3 = 0.9;
247  float64_t gTd;
248  float64_t last_sigma_k=0;
249 
250  float64_t initial_primal_obj;
251  int32_t suff_decrease_cond=0;
252  float64_t decrease_proportion = 0.2; // start from 0.2 first
253 
254  float64_t z_k_norm;
255  float64_t last_z_k_norm=0;
256 
257  /* warm start */
258  SGVector<float64_t> w_b = m_w.clone();
259 
260  iter = 0;
261  size_active = 0;
262  G = NULL;
263 
264  new_constraint = find_cutting_plane(&margin);
265  value = margin - new_constraint.dense_dot(1.0, m_w.vector, m_w.vlen, 0);
266 
267  primal_obj_b = primal_obj = 0.5*m_w.dot(m_w.vector, m_w.vector, m_w.vlen)+m_C*value;
268  primal_lower_bound = 0;
269  expected_descent = -primal_obj_b;
270  initial_primal_obj = primal_obj_b;
271 
272  SG_INFO("Running CCCP inner loop solver: ")
273 
274  while ((!suff_decrease_cond)&&(expected_descent<-m_eps)&&(iter<m_max_iter))
275  {
276  iter+=1;
277  size_active+=1;
278 
279  SG_DEBUG("ITER %d\n", iter)
280  SG_PRINT(".")
281 
282  /* add constraint */
283  dXc.resize_array(size_active);
284  dXc[size_active - 1] = new_constraint;
285  // dXc[size_active - 1].add(new_constraint);
286  /*
287  dXc = (DOC**)realloc(dXc, sizeof(DOC*)*size_active);
288  dXc[size_active-1] = (DOC*)malloc(sizeof(DOC));
289  dXc[size_active-1]->fvec = new_constraint;
290  dXc[size_active-1]->slackid = 1; // only one common slackid (one-slack)
291  dXc[size_active-1]->costfactor = 1.0;
292  */
293  delta.resize_vector(size_active);
294  delta[size_active-1] = margin;
295  alpha.resize_vector(size_active);
296  alpha[size_active-1] = 0.0;
297  idle.resize_vector(size_active);
298  idle[size_active-1] = 0;
299  /* proximal point */
300  proximal_rhs.resize_vector(size_active);
301  cut_error.resize_vector(size_active);
302  // note g_i = - new_constraint
303  cut_error[size_active-1] = m_C*(new_constraint.dense_dot(1.0, w_b.vector, w_b.vlen, 0) - new_constraint.dense_dot(1.0, m_w.vector, m_w.vlen, 0));
304  cut_error[size_active-1] += (primal_obj_b - 0.5*w_b.dot(w_b.vector, w_b.vector, w_b.vlen));
305  cut_error[size_active-1] -= (primal_obj - 0.5*m_w.dot(m_w.vector, m_w.vector, m_w.vlen));
306 
307  gammaG0.resize_vector(size_active);
308 
309  /* update Gram matrix */
310  G = SG_REALLOC(float64_t*, G, size_active-1, size_active);
311  G[size_active - 1] = NULL;
312  for (index_t j=0; j < size_active;j++)
313  {
314  G[j] = SG_REALLOC(float64_t, G[j], size_active-1, size_active);
315  }
316  for (index_t j=0; j < size_active-1; j++)
317  {
318  G[size_active-1][j] = dXc[size_active-1].sparse_dot(dXc[j]);
319  G[j][size_active-1] = G[size_active-1][j];
320  }
321  G[size_active-1][size_active-1] = dXc[size_active-1].sparse_dot(dXc[size_active-1]);
322 
323  /* update gammaG0 */
324  if (null_step==1)
325  {
326  gammaG0[size_active-1] = dXc[size_active-1].dense_dot(1.0, w_b.vector, w_b.vlen, 0);
327  }
328  else
329  {
330  for (index_t i = 0; i < size_active; i++)
331  gammaG0[i] = dXc[i].dense_dot(1.0, w_b.vector, w_b.vlen, 0);
332  }
333 
334  /* update proximal_rhs */
335  for (index_t i = 0; i < size_active; i++)
336  {
337  switch(m_qp_type)
338  {
339  case MOSEK:
340  proximal_rhs[i] = delta[i] - rho/(1+rho)*gammaG0[i];
341  break;
342  case SVMLIGHT:
343  proximal_rhs[i] = (1+rho)*delta[i] - rho*gammaG0[i];
344  break;
345  default:
346  SG_ERROR("Invalid QPType: %d\n", m_qp_type)
347  }
348  }
349 
350  switch(m_qp_type)
351  {
352  case MOSEK:
353  /* solve QP to update alpha */
354  dual_obj = 0;
355  mosek_qp_optimize(G, proximal_rhs.vector, alpha.vector, size_active, &dual_obj, rho);
356  break;
357  case SVMLIGHT:
358  /* TODO: port required functionality from the latest SVM^light into shogun
359  * in order to be able to support this
360  *
361  if (size_active>1)
362  {
363  if (svmModel!=NULL)
364  free_model(svmModel,0);
365  svmModel = (MODEL*)my_malloc(sizeof(MODEL));
366  svm_learn_optimization(dXc,proximal_rhs,size_active,sm->sizePsi,&lparm,&kparm,NULL,svmModel,alpha);
367  }
368  else
369  {
370  ASSERT(size_active==1)
371  alpha[0] = m_C;
372  }
373  */
374  break;
375  default:
376  SG_ERROR("Invalid QPType: %d\n", m_qp_type)
377  }
378 
379  /* DEBUG */
380  //printf("r: %d\n", r); fflush(stdout);
381  //printf("dual: %.16lf\n", dual_obj);
382  /* END DEBUG */
383 
384  m_w.zero();
385  for (index_t j = 0; j < size_active; j++)
386  {
387  if (alpha[j]>m_C*m_alpha_thrld)
388  {
389  // TODO: move this to SGVector
390  // basically it's vector[i]= scale*sparsevector[i]
391  for (index_t k = 0; k < dXc[j].num_feat_entries; k++)
392  {
393  index_t idx = dXc[j].features[k].feat_index;
394  m_w[idx] += alpha[j]/(1+rho)*dXc[j].features[k].entry;
395  }
396  }
397  }
398 
399  if (m_qp_type == SVMLIGHT)
400  {
401  /* compute dual obj */
402  dual_obj = +0.5*(1+rho)*m_w.dot(m_w.vector, m_w.vector, m_w.vlen);
403  for (int32_t j=0;j<size_active;j++)
404  dual_obj -= proximal_rhs[j]/(1+rho)*alpha[j];
405  }
406 
407  z_k_norm = CMath::sqrt(m_w.dot(m_w.vector, m_w.vector, m_w.vlen));
408  m_w.vec1_plus_scalar_times_vec2(m_w.vector, rho/(1+rho), w_b.vector, w_b.vlen);
409 
410  /* detect if step size too small */
411  sigma_k = 0;
412  alphasum = 0;
413  for (index_t j = 0; j < size_active; j++)
414  {
415  sigma_k += alpha[j]*cut_error[j];
416  alphasum+=alpha[j];
417  }
418  sigma_k/=m_C;
419  gTd = -m_C*(new_constraint.dense_dot(1.0, m_w.vector, m_w.vlen, 0)
420  - new_constraint.dense_dot(1.0, w_b.vector, w_b.vlen, 0));
421 
422  for (index_t j = 0; j < size_active; j++)
423  SG_DEBUG("alpha[%d]: %.8g, cut_error[%d]: %.8g\n", j, alpha[j], j, cut_error[j])
424  SG_DEBUG("sigma_k: %.8g\n", sigma_k)
425  SG_DEBUG("alphasum: %.8g\n", alphasum)
426  SG_DEBUG("g^T d: %.8g\n", gTd)
427 
428  /* update cleanup information */
429  for (index_t j = 0; j < size_active; j++)
430  {
431  if (alpha[j]<m_alpha_thrld*m_C)
432  idle[j]++;
433  else
434  idle[j]=0;
435  }
436 
437  new_constraint = find_cutting_plane(&margin);
438  value = margin - new_constraint.dense_dot(1.0, m_w.vector, m_w.vlen, 0);
439 
440  /* print primal objective */
441  primal_obj = 0.5*m_w.dot(m_w.vector, m_w.vector, m_w.vlen)+m_C*value;
442 
443  SG_DEBUG("ITER PRIMAL_OBJ %.4f\n", primal_obj)
444 
445  temp_var = w_b.dot(w_b.vector, w_b.vector, w_b.vlen);
446  proximal_term = 0.0;
447  for (index_t i=0; i < m_model->get_dim(); i++)
448  proximal_term += (m_w[i]-w_b[i])*(m_w[i]-w_b[i]);
449 
450  reg_master_obj = -dual_obj+0.5*rho*temp_var/(1+rho);
451  expected_descent = reg_master_obj - primal_obj_b;
452 
453  v_k = (reg_master_obj - proximal_term*rho/2) - primal_obj_b;
454 
455  primal_lower_bound = CMath::max(primal_lower_bound, reg_master_obj - 0.5*rho*(1+rho)*proximal_term);
456 
457  SG_DEBUG("ITER REG_MASTER_OBJ: %.4f\n", reg_master_obj)
458  SG_DEBUG("ITER EXPECTED_DESCENT: %.4f\n", expected_descent)
459  SG_DEBUG("ITER PRIMLA_OBJ_B: %.4f\n", primal_obj_b)
460  SG_DEBUG("ITER RHO: %.4f\n", rho)
461  SG_DEBUG("ITER ||w-w_b||^2: %.4f\n", proximal_term)
462  SG_DEBUG("ITER PRIMAL_LOWER_BOUND: %.4f\n", primal_lower_bound)
463  SG_DEBUG("ITER V_K: %.4f\n", v_k)
464  SG_DEBUG("ITER margin: %.4f\n", margin)
465  SG_DEBUG("ITER psi*-psi: %.4f\n", value-margin)
466 
467  obj_difference = primal_obj - primal_obj_b;
468 
469  if (primal_obj<primal_obj_b+kappa*expected_descent)
470  {
471  /* extra condition to be met */
472  if ((gTd>m2*v_k)||(rho<min_rho+1E-8))
473  {
474  SG_DEBUG("SERIOUS STEP\n")
475 
476  /* update cut_error */
477  for (index_t i = 0; i < size_active; i++)
478  {
479  cut_error[i] -= (primal_obj_b - 0.5*w_b.dot(w_b.vector, w_b.vector, w_b.vlen));
480  cut_error[i] -= m_C*dXc[i].dense_dot(1.0, w_b.vector, w_b.vlen, 0);
481  cut_error[i] += (primal_obj - 0.5*m_w.dot(m_w, m_w, m_w.vlen));
482  cut_error[i] += m_C*dXc[i].dense_dot(1.0, m_w.vector, m_w.vlen, 0);
483  }
484  primal_obj_b = primal_obj;
485  /* copy w_b <- m_w */
486  for (index_t i=0; i < m_model->get_dim(); i++)
487  {
488  w_b[i] = m_w[i];
489  }
490  null_step = 0;
491  serious_counter++;
492  }
493  else
494  {
495  /* increase step size */
496  SG_DEBUG("NULL STEP: SS(ii) FAILS.\n")
497 
498  serious_counter--;
499  rho = CMath::max(rho/10,min_rho);
500  }
501  }
502  else
503  { /* no sufficient decrease */
504  serious_counter--;
505 
506  if ((cut_error[size_active-1]>m3*last_sigma_k)&&(CMath::abs(obj_difference)>last_z_k_norm+last_sigma_k))
507  {
508  SG_DEBUG("NULL STEP: NS(ii) FAILS.\n")
509  rho = CMath::min(10*rho,m_max_rho);
510  }
511  else
512  SG_DEBUG("NULL STEP\n")
513  }
514  /* update last_sigma_k */
515  last_sigma_k = sigma_k;
516  last_z_k_norm = z_k_norm;
517 
518 
519  /* break away from while loop if more than certain proportioal decrease in primal objective */
520  if (primal_obj_b/initial_primal_obj<1-decrease_proportion)
521  suff_decrease_cond = 1;
522 
523  /* clean up */
524  if (iter % m_cleanup_check == 0)
525  {
526  size_active = resize_cleanup(size_active, idle, alpha, delta, gammaG0, proximal_rhs, &G, dXc, cut_error);
527  ASSERT(size_active == proximal_rhs.vlen)
528  }
529  } // end cutting plane while loop
530 
531  SG_INFO(" Inner loop optimization finished.\n")
532 
533  for (index_t j = 0; j < size_active; j++)
534  free(G[j]);
535  free(G);
536 
537  /* copy */
538  for (index_t i=0; i < m_model->get_dim(); i++)
539  m_w[i] = w_b[i];
540 
541  m_primal_obj = primal_obj_b;
542 
543  return true;
544 }
545 
546 SGSparseVector<float64_t> CCCSOSVM::find_cutting_plane(float64_t* margin)
547 {
548  SGVector<float64_t> new_constraint(m_model->get_dim());
549  int32_t psi_size = m_model->get_dim();
550 
551  index_t num_samples = m_model->get_features()->get_num_vectors();
552  /* find cutting plane */
553  *margin = 0;
554  new_constraint.zero();
555  for (index_t i = 0; i < num_samples; i++)
556  {
557  CResultSet* result = m_model->argmax(m_w, i);
558  new_constraint.add(result->psi_truth);
559  result->psi_pred.scale(-1.0);
560  new_constraint.add(result->psi_pred);
561  /*
562  printf("%.16lf %.16lf\n",
563  SGVector<float64_t>::dot(result->psi_truth.vector, result->psi_truth.vector, result->psi_truth.vlen),
564  SGVector<float64_t>::dot(result->psi_pred.vector, result->psi_pred.vector, result->psi_pred.vlen));
565  */
566  *margin += result->delta;
567  SG_UNREF(result);
568  }
569  /* scaling */
570  float64_t scale = 1/(float64_t)num_samples;
571  new_constraint.scale(scale);
572  *margin *= scale;
573 
574  /* find the nnz elements in new_constraint */
575  index_t l = 0;
576  for (index_t i=0; i < psi_size; i++)
577  {
578  if (CMath::abs(new_constraint[i])>1E-10)
579  l++; // non-zero
580  }
581  /* TODO: does this really work good?
582  l = CMath::get_num_nonzero(new_constraint.vector, new_constraint.vlen);
583  */
584  /* create a sparse vector of the nnz of new_constraint */
585  SGSparseVector<float64_t> cut_plane(l);
586  index_t k = 0;
587  for (index_t i = 0; i < psi_size; i++)
588  {
589  if (CMath::abs(new_constraint[i])>1E-10)
590  {
591  cut_plane.features[k].feat_index = i;
592  cut_plane.features[k].entry = new_constraint[i];
593  k++;
594  }
595  }
596 
597  return cut_plane;
598 }
599 
600 int32_t CCCSOSVM::resize_cleanup(int32_t size_active, SGVector<int32_t>& idle, SGVector<float64_t>&alpha,
601  SGVector<float64_t>& delta, SGVector<float64_t>& gammaG0,
602  SGVector<float64_t>& proximal_rhs, float64_t ***ptr_G,
604 {
605  int32_t i, j, new_size_active;
606  index_t k;
607 
608  float64_t **G = *ptr_G;
609 
610  i=0;
611  while ((i<size_active)&&(idle[i]<m_idle_iter))
612  i++;
613 
614  j=i;
615  while((j<size_active)&&(idle[j]>=m_idle_iter))
616  j++;
617 
618  while (j<size_active)
619  {
620  /* copying */
621  alpha[i] = alpha[j];
622  delta[i] = delta[j];
623  gammaG0[i] = gammaG0[j];
624  cut_error[i] = cut_error[j];
625 
626  free(G[i]);
627  G[i] = G[j];
628  G[j] = NULL;
629  // free_example(dXc[i],0);
630  dXc[i] = dXc[j];
631 // dXc[j] = NULL;
632 
633  i++;
634  j++;
635  while((j<size_active)&&(idle[j]>=m_idle_iter))
636  j++;
637  }
638  for (k=i;k<size_active;k++)
639  {
640  if (G[k]!=NULL) free(G[k]);
641 // if (dXc[k].num_feat_entries > 0) SG_UNREF(dXc[k]);
642  }
643  new_size_active = i;
644  alpha.resize_vector(new_size_active);
645  delta.resize_vector(new_size_active);
646  gammaG0.resize_vector(new_size_active);
647  proximal_rhs.resize_vector(new_size_active);
648  G = SG_REALLOC(float64_t*, G, size_active, new_size_active);
649  dXc.resize_array(new_size_active);
650  cut_error.resize_vector(new_size_active);
651 
652  /* resize G and idle */
653  i=0;
654  while ((i<size_active)&&(idle[i]<m_idle_iter))
655  i++;
656 
657  j=i;
658  while((j<size_active)&&(idle[j]>=m_idle_iter))
659  j++;
660 
661  while (j<size_active)
662  {
663  idle[i] = idle[j];
664  for (k=0;k<new_size_active;k++)
665  G[k][i] = G[k][j];
666 
667  i++;
668  j++;
669  while((j<size_active)&&(idle[j]>=m_idle_iter))
670  j++;
671  }
672  idle.resize_vector(new_size_active);
673  for (k=0;k<new_size_active;k++)
674  G[k] = SG_REALLOC(float64_t, G[k], size_active, new_size_active);
675 
676  *ptr_G = G;
677 
678  return new_size_active;
679 }
680 
681 void CCCSOSVM::init()
682 {
683  m_C = 1.0;
684  m_eps = 1E-3;
685  m_alpha_thrld = 1E-14;
686  m_cleanup_check = 100;
687  m_idle_iter = 20;
688  m_max_iter = 1000;
689  m_max_rho = m_C;
690  m_primal_obj = CMath::INFTY;
691  m_qp_type = MOSEK;
692 
693  SG_ADD(&m_C, "m_C", "C", MS_NOT_AVAILABLE);
694  SG_ADD(&m_eps, "m_eps", "Epsilon", MS_NOT_AVAILABLE);
695  SG_ADD(&m_alpha_thrld, "m_alpha_thrld", "Alpha threshold", MS_NOT_AVAILABLE);
696  SG_ADD(&m_cleanup_check, "m_cleanup_check", "Cleanup after given number of iterations", MS_NOT_AVAILABLE);
697  SG_ADD(&m_idle_iter, "m_idle_iter", "Maximum number of idle iteration", MS_NOT_AVAILABLE);
698  SG_ADD(&m_max_iter, "m_max_iter", "Maximum number of iterations", MS_NOT_AVAILABLE);
699  SG_ADD(&m_max_rho, "m_max_rho", "Max rho", MS_NOT_AVAILABLE);
700  SG_ADD(&m_primal_obj, "m_primal_obj", "Primal objective value", MS_NOT_AVAILABLE);
701  SG_ADD((machine_int_t*) &m_qp_type, "m_qp_type", "QP Solver Type", MS_NOT_AVAILABLE);
702 }
703 
705 {
706  return CT_CCSOSVM;
707 }

SHOGUN Machine Learning Toolbox - Documentation