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

SHOGUN Machine Learning Toolbox - Documentation