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

SHOGUN Machine Learning Toolbox - Documentation