SHOGUN  v3.0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
libbmrm.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  * libbmrm.h: Implementation of the BMRM solver for SO training
8  *
9  * Copyright (C) 2012 Michal Uricar, uricamic@cmp.felk.cvut.cz
10  *
11  * Implementation of the BMRM solver
12  *--------------------------------------------------------------------- */
13 
15 #include <shogun/lib/external/libqp.h>
16 #include <shogun/lib/Time.h>
17 #include <shogun/io/SGIO.h>
18 
19 namespace shogun
20 {
21 static const uint32_t QPSolverMaxIter=0xFFFFFFFF;
22 static const float64_t epsilon=0.0;
23 
24 static float64_t *H;
25 static uint32_t BufSize;
26 
28  bmrm_ll** tail,
29  bool* map,
30  float64_t* A,
31  uint32_t free_idx,
32  float64_t* cp_data,
33  uint32_t dim)
34 {
35  ASSERT(map[free_idx])
36 
37  LIBBMRM_MEMCPY(A+free_idx*dim, cp_data, dim*sizeof(float64_t));
38  map[free_idx]=false;
39 
41 
42  if (cp==NULL)
43  {
44  SG_SERROR("Out of memory.\n")
45  return;
46  }
47 
48  cp->address=A+(free_idx*dim);
49  cp->prev=*tail;
50  cp->next=NULL;
51  cp->idx=free_idx;
52  (*tail)->next=cp;
53  *tail=cp;
54 }
55 
57  bmrm_ll** head,
58  bmrm_ll** tail,
59  bool* map,
60  float64_t* icp)
61 {
62  bmrm_ll *cp_list_ptr=*head;
63 
64  while(cp_list_ptr->address != icp)
65  {
66  cp_list_ptr=cp_list_ptr->next;
67  }
68 
69  if (cp_list_ptr==*head)
70  {
71  *head=(*head)->next;
72  cp_list_ptr->next->prev=NULL;
73  }
74  else if (cp_list_ptr==*tail)
75  {
76  *tail=(*tail)->prev;
77  cp_list_ptr->prev->next=NULL;
78  }
79  else
80  {
81  cp_list_ptr->prev->next=cp_list_ptr->next;
82  cp_list_ptr->next->prev=cp_list_ptr->prev;
83  }
84 
85  map[cp_list_ptr->idx]=true;
86  LIBBMRM_FREE(cp_list_ptr);
87 }
88 
89 void clean_icp(ICP_stats* icp_stats,
90  BmrmStatistics& bmrm,
91  bmrm_ll** head,
92  bmrm_ll** tail,
93  float64_t*& Hmat,
94  float64_t*& diag_H,
95  float64_t*& beta,
96  bool*& map,
97  uint32_t cleanAfter,
98  float64_t*& b,
99  uint32_t*& I,
100  uint32_t cp_models
101  )
102 {
103  /* find ICP */
104  uint32_t cntICP=0;
105  uint32_t cntACP=0;
106  bmrm_ll* cp_ptr=*head;
107  uint32_t tmp_idx=0;
108 
109  while (cp_ptr != *tail)
110  {
111  if (icp_stats->ICPcounter[tmp_idx++]>=cleanAfter)
112  {
113  icp_stats->ICPs[cntICP++]=cp_ptr->address;
114  }
115  else
116  {
117  icp_stats->ACPs[cntACP++]=tmp_idx-1;
118  }
119 
120  cp_ptr=cp_ptr->next;
121  }
122 
123  /* do ICP removal */
124  if (cntICP > 0)
125  {
126  uint32_t nCP_new=bmrm.nCP-cntICP;
127 
128  for (uint32_t i=0; i<cntICP; ++i)
129  {
130  tmp_idx=0;
131  cp_ptr=*head;
132 
133  while(cp_ptr->address != icp_stats->ICPs[i])
134  {
135  cp_ptr=cp_ptr->next;
136  tmp_idx++;
137  }
138 
139  remove_cutting_plane(head, tail, map, icp_stats->ICPs[i]);
140 
141  LIBBMRM_MEMMOVE(b+tmp_idx, b+tmp_idx+1,
142  (bmrm.nCP+cp_models-tmp_idx)*sizeof(float64_t));
143  LIBBMRM_MEMMOVE(beta+tmp_idx, beta+tmp_idx+1,
144  (bmrm.nCP-tmp_idx)*sizeof(float64_t));
145  LIBBMRM_MEMMOVE(diag_H+tmp_idx, diag_H+tmp_idx+1,
146  (bmrm.nCP-tmp_idx)*sizeof(float64_t));
147  LIBBMRM_MEMMOVE(I+tmp_idx, I+tmp_idx+1,
148  (bmrm.nCP-tmp_idx)*sizeof(uint32_t));
149  LIBBMRM_MEMMOVE(icp_stats->ICPcounter+tmp_idx, icp_stats->ICPcounter+tmp_idx+1,
150  (bmrm.nCP-tmp_idx)*sizeof(uint32_t));
151  }
152 
153  /* H */
154  for (uint32_t i=0; i < nCP_new; ++i)
155  {
156  for (uint32_t j=0; j < nCP_new; ++j)
157  {
158  icp_stats->H_buff[LIBBMRM_INDEX(i, j, icp_stats->maxCPs)]=
159  Hmat[LIBBMRM_INDEX(icp_stats->ACPs[i], icp_stats->ACPs[j], icp_stats->maxCPs)];
160  }
161  }
162 
163  for (uint32_t i=0; i<nCP_new; ++i)
164  for (uint32_t j=0; j<nCP_new; ++j)
165  Hmat[LIBBMRM_INDEX(i, j, icp_stats->maxCPs)]=
166  icp_stats->H_buff[LIBBMRM_INDEX(i, j, icp_stats->maxCPs)];
167 
168  bmrm.nCP=nCP_new;
169  }
170 }
171 
172 /*----------------------------------------------------------------------
173  Returns pointer at i-th column of Hessian matrix.
174  ----------------------------------------------------------------------*/
175 static const float64_t *get_col( uint32_t i)
176 {
177  return( &H[ BufSize*i ] );
178 }
179 
181  CDualLibQPBMSOSVM *machine,
182  float64_t* W,
183  float64_t TolRel,
184  float64_t TolAbs,
185  float64_t _lambda,
186  uint32_t _BufSize,
187  bool cleanICP,
188  uint32_t cleanAfter,
189  float64_t K,
190  uint32_t Tmax,
191  bool verbose)
192 {
193  BmrmStatistics bmrm;
194  libqp_state_T qp_exitflag={0, 0, 0, 0};
195  float64_t *b, *beta, *diag_H, *prevW;
196  float64_t R, *subgrad, *A, QPSolverTolRel, C=1.0, wdist=0.0;
197  floatmax_t rsum, sq_norm_W, sq_norm_Wdiff=0.0;
198  uint32_t *I;
199  uint8_t S=1;
200  CStructuredModel* model=machine->get_model();
201  uint32_t nDim=model->get_dim();
202  CSOSVMHelper* helper = NULL;
203 
204  CTime ttime;
205  float64_t tstart, tstop;
206 
207  bmrm_ll *CPList_head, *CPList_tail, *cp_ptr, *cp_ptr2, *cp_list=NULL;
208  float64_t *A_1=NULL, *A_2=NULL;
209  bool *map=NULL;
210 
211 
212  tstart=ttime.cur_time_diff(false);
213 
214  BufSize=_BufSize;
215  QPSolverTolRel=1e-9;
216 
217  H=NULL;
218  b=NULL;
219  beta=NULL;
220  A=NULL;
221  subgrad=NULL;
222  diag_H=NULL;
223  I=NULL;
224  prevW=NULL;
225 
227 
228  if (H==NULL)
229  {
230  bmrm.exitflag=-2;
231  goto cleanup;
232  }
233 
234  A= (float64_t*) LIBBMRM_CALLOC(nDim*BufSize, float64_t);
235 
236  if (A==NULL)
237  {
238  bmrm.exitflag=-2;
239  goto cleanup;
240  }
241 
242  b= (float64_t*) LIBBMRM_CALLOC(BufSize, float64_t);
243 
244  if (b==NULL)
245  {
246  bmrm.exitflag=-2;
247  goto cleanup;
248  }
249 
250  beta= (float64_t*) LIBBMRM_CALLOC(BufSize, float64_t);
251 
252  if (beta==NULL)
253  {
254  bmrm.exitflag=-2;
255  goto cleanup;
256  }
257 
258  subgrad= (float64_t*) LIBBMRM_CALLOC(nDim, float64_t);
259 
260  if (subgrad==NULL)
261  {
262  bmrm.exitflag=-2;
263  goto cleanup;
264  }
265 
266  diag_H= (float64_t*) LIBBMRM_CALLOC(BufSize, float64_t);
267 
268  if (diag_H==NULL)
269  {
270  bmrm.exitflag=-2;
271  goto cleanup;
272  }
273 
274  I= (uint32_t*) LIBBMRM_CALLOC(BufSize, uint32_t);
275 
276  if (I==NULL)
277  {
278  bmrm.exitflag=-2;
279  goto cleanup;
280  }
281 
282  ICP_stats icp_stats;
283  icp_stats.maxCPs = BufSize;
284 
285  icp_stats.ICPcounter= (uint32_t*) LIBBMRM_CALLOC(BufSize, uint32_t);
286  if (icp_stats.ICPcounter==NULL)
287  {
288  bmrm.exitflag=-2;
289  goto cleanup;
290  }
291 
292  icp_stats.ICPs= (float64_t**) LIBBMRM_CALLOC(BufSize, float64_t*);
293  if (icp_stats.ICPs==NULL)
294  {
295  bmrm.exitflag=-2;
296  goto cleanup;
297  }
298 
299  icp_stats.ACPs= (uint32_t*) LIBBMRM_CALLOC(BufSize, uint32_t);
300  if (icp_stats.ACPs==NULL)
301  {
302  bmrm.exitflag=-2;
303  goto cleanup;
304  }
305 
306  /* Temporary buffers for ICP removal */
307  icp_stats.H_buff= (float64_t*) LIBBMRM_CALLOC(BufSize*BufSize, float64_t);
308  if (icp_stats.H_buff==NULL)
309  {
310  bmrm.exitflag=-2;
311  goto cleanup;
312  }
313 
314  map= (bool*) LIBBMRM_CALLOC(BufSize, bool);
315 
316  if (map==NULL)
317  {
318  bmrm.exitflag=-2;
319  goto cleanup;
320  }
321 
322  memset( (bool*) map, true, BufSize);
323 
324  cp_list= (bmrm_ll*) LIBBMRM_CALLOC(1, bmrm_ll);
325 
326  if (cp_list==NULL)
327  {
328  bmrm.exitflag=-2;
329  goto cleanup;
330  }
331 
332  prevW= (float64_t*) LIBBMRM_CALLOC(nDim, float64_t);
333 
334  if (prevW==NULL)
335  {
336  bmrm.exitflag=-2;
337  goto cleanup;
338  }
339 
343 
344  /* Iinitial solution */
345  R=machine->risk(subgrad, W);
346 
347  bmrm.nCP=0;
348  bmrm.nIter=0;
349  bmrm.exitflag=0;
350 
351  b[0]=-R;
352 
353  /* Cutting plane auxiliary double linked list */
354 
355  LIBBMRM_MEMCPY(A, subgrad, nDim*sizeof(float64_t));
356  map[0]=false;
357  cp_list->address=&A[0];
358  cp_list->idx=0;
359  cp_list->prev=NULL;
360  cp_list->next=NULL;
361  CPList_head=cp_list;
362  CPList_tail=cp_list;
363 
364  /* Compute initial value of Fp, Fd, assuming that W is zero vector */
365 
366  sq_norm_W=0;
367  bmrm.Fp=R+0.5*_lambda*sq_norm_W;
368  bmrm.Fd=-LIBBMRM_PLUS_INF;
369 
370  tstop=ttime.cur_time_diff(false);
371 
372  /* Verbose output */
373 
374  if (verbose)
375  SG_SDEBUG("%4d: tim=%.3lf, Fp=%lf, Fd=%lf, R=%lf\n",
376  bmrm.nIter, tstop-tstart, bmrm.Fp, bmrm.Fd, R);
377 
378  /* store Fp, Fd and wdist history */
379  bmrm.hist_Fp[0]=bmrm.Fp;
380  bmrm.hist_Fd[0]=bmrm.Fd;
381  bmrm.hist_wdist[0]=0.0;
382 
383  if (verbose)
384  helper = machine->get_helper();
385 
386  /* main loop */
387 
388  while (bmrm.exitflag==0)
389  {
390  tstart=ttime.cur_time_diff(false);
391  bmrm.nIter++;
392 
393  /* Update H */
394 
395  if (bmrm.nCP>0)
396  {
397  A_2=get_cutting_plane(CPList_tail);
398  cp_ptr=CPList_head;
399 
400  for (uint32_t i=0; i<bmrm.nCP; ++i)
401  {
402  A_1=get_cutting_plane(cp_ptr);
403  cp_ptr=cp_ptr->next;
404  rsum= SGVector<float64_t>::dot(A_1, A_2, nDim);
405 
406  H[LIBBMRM_INDEX(bmrm.nCP, i, BufSize)]
407  = H[LIBBMRM_INDEX(i, bmrm.nCP, BufSize)]
408  = rsum/_lambda;
409  }
410  }
411 
412  A_2=get_cutting_plane(CPList_tail);
413  rsum = SGVector<float64_t>::dot(A_2, A_2, nDim);
414 
415  H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)]=rsum/_lambda;
416 
417  diag_H[bmrm.nCP]=H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)];
418  I[bmrm.nCP]=1;
419 
420  bmrm.nCP++;
421  beta[bmrm.nCP]=0.0; // [beta; 0]
422 
423 #if 0
424  /* TODO: scaling...*/
425  float64_t scale = SGVector<float64_t>::max(diag_H, BufSize)/(1000.0*_lambda);
426  SGVector<float64_t> sb(bmrm.nCP);
427  sb.zero();
428  sb.vec1_plus_scalar_times_vec2(sb.vector, 1/scale, b, bmrm.nCP);
429 
430  SGVector<float64_t> sh(bmrm.nCP);
431  sh.zero();
432  sb.vec1_plus_scalar_times_vec2(sh.vector, 1/scale, diag_H, bmrm.nCP);
433 
434  qp_exitflag =
435  libqp_splx_solver(&get_col, sh.vector, sb.vector, &C, I, &S, beta,
436  bmrm.nCP, QPSolverMaxIter, 0.0, QPSolverTolRel, -LIBBMRM_PLUS_INF, 0);
437 #else
438  /* call QP solver */
439  qp_exitflag=libqp_splx_solver(&get_col, diag_H, b, &C, I, &S, beta,
440  bmrm.nCP, QPSolverMaxIter, 0.0, QPSolverTolRel, -LIBBMRM_PLUS_INF, 0);
441 #endif
442 
443  bmrm.qp_exitflag=qp_exitflag.exitflag;
444 
445  /* Update ICPcounter (add one to unused and reset used)
446  * + compute number of active CPs */
447  bmrm.nzA=0;
448 
449  for (uint32_t aaa=0; aaa<bmrm.nCP; ++aaa)
450  {
451  if (beta[aaa]>epsilon)
452  {
453  ++bmrm.nzA;
454  icp_stats.ICPcounter[aaa]=0;
455  }
456  else
457  {
458  icp_stats.ICPcounter[aaa]+=1;
459  }
460  }
461 
462  /* W update */
463  memset(W, 0, sizeof(float64_t)*nDim);
464  cp_ptr=CPList_head;
465  for (uint32_t j=0; j<bmrm.nCP; ++j)
466  {
467  A_1=get_cutting_plane(cp_ptr);
468  cp_ptr=cp_ptr->next;
469  SGVector<float64_t>::vec1_plus_scalar_times_vec2(W, -beta[j]/_lambda, A_1, nDim);
470  }
471 
472  /* risk and subgradient computation */
473  R = machine->risk(subgrad, W);
474  add_cutting_plane(&CPList_tail, map, A,
475  find_free_idx(map, BufSize), subgrad, nDim);
476 
477  sq_norm_W=SGVector<float64_t>::dot(W, W, nDim);
478  b[bmrm.nCP]=SGVector<float64_t>::dot(subgrad, W, nDim) - R;
479 
480  sq_norm_Wdiff=0.0;
481  for (uint32_t j=0; j<nDim; ++j)
482  {
483  sq_norm_Wdiff+=(W[j]-prevW[j])*(W[j]-prevW[j]);
484  }
485 
486  bmrm.Fp=R+0.5*_lambda*sq_norm_W;
487  bmrm.Fd=-qp_exitflag.QP;
488  wdist=CMath::sqrt(sq_norm_Wdiff);
489 
490  /* Stopping conditions */
491 
492  if (bmrm.Fp - bmrm.Fd <= TolRel*LIBBMRM_ABS(bmrm.Fp))
493  bmrm.exitflag=1;
494 
495  if (bmrm.Fp - bmrm.Fd <= TolAbs)
496  bmrm.exitflag=2;
497 
498  if (bmrm.nCP >= BufSize)
499  bmrm.exitflag=-1;
500 
501  tstop=ttime.cur_time_diff(false);
502 
503  /* Verbose output */
504 
505  if (verbose)
506  SG_SDEBUG("%4d: tim=%.3lf, Fp=%lf, Fd=%lf, (Fp-Fd)=%lf, (Fp-Fd)/Fp=%lf, R=%lf, nCP=%d, nzA=%d, QPexitflag=%d\n",
507  bmrm.nIter, tstop-tstart, bmrm.Fp, bmrm.Fd, bmrm.Fp-bmrm.Fd,
508  (bmrm.Fp-bmrm.Fd)/bmrm.Fp, R, bmrm.nCP, bmrm.nzA, qp_exitflag.exitflag);
509 
510  /* Keep Fp, Fd and w_dist history */
511  bmrm.hist_Fp[bmrm.nIter]=bmrm.Fp;
512  bmrm.hist_Fd[bmrm.nIter]=bmrm.Fd;
513  bmrm.hist_wdist[bmrm.nIter]=wdist;
514 
515  /* Check size of Buffer */
516 
517  if (bmrm.nCP>=BufSize)
518  {
519  bmrm.exitflag=-2;
520  SG_SERROR("Buffer exceeded.\n")
521  }
522 
523  /* keep W (for wdist history track) */
524  LIBBMRM_MEMCPY(prevW, W, nDim*sizeof(float64_t));
525 
526  /* Inactive Cutting Planes (ICP) removal */
527  if (cleanICP)
528  {
529  clean_icp(&icp_stats, bmrm, &CPList_head, &CPList_tail, H, diag_H, beta, map, cleanAfter, b, I);
530  }
531 
532  /* Debug: compute objective and training error */
533  if (verbose)
534  {
535  SGVector<float64_t> w_debug(W, nDim, false);
536  float64_t primal = CSOSVMHelper::primal_objective(w_debug, model, _lambda);
537  float64_t train_error = CSOSVMHelper::average_loss(w_debug, model);
538  helper->add_debug_info(primal, bmrm.nIter, train_error);
539  }
540  } /* end of main loop */
541 
542  if (verbose)
543  {
544  helper->terminate();
545  SG_UNREF(helper);
546  }
547 
548  bmrm.hist_Fp.resize_vector(bmrm.nIter);
549  bmrm.hist_Fd.resize_vector(bmrm.nIter);
550  bmrm.hist_wdist.resize_vector(bmrm.nIter);
551 
552  cp_ptr=CPList_head;
553 
554  while(cp_ptr!=NULL)
555  {
556  cp_ptr2=cp_ptr;
557  cp_ptr=cp_ptr->next;
558  LIBBMRM_FREE(cp_ptr2);
559  cp_ptr2=NULL;
560  }
561 
562  cp_list=NULL;
563 
564 cleanup:
565 
566  LIBBMRM_FREE(H);
567  LIBBMRM_FREE(b);
568  LIBBMRM_FREE(beta);
569  LIBBMRM_FREE(A);
570  LIBBMRM_FREE(subgrad);
571  LIBBMRM_FREE(diag_H);
572  LIBBMRM_FREE(I);
573  LIBBMRM_FREE(icp_stats.ICPcounter);
574  LIBBMRM_FREE(icp_stats.ICPs);
575  LIBBMRM_FREE(icp_stats.ACPs);
576  LIBBMRM_FREE(icp_stats.H_buff);
577  LIBBMRM_FREE(map);
578  LIBBMRM_FREE(prevW);
579 
580  if (cp_list)
581  LIBBMRM_FREE(cp_list);
582 
583  SG_UNREF(model);
584 
585  return(bmrm);
586 }
587 }
#define LIBBMRM_CALLOC(x, y)
Definition: libbmrm.h:23
Class Time that implements a stopwatch based on either cpu time or wall clock time.
Definition: Time.h:46
static float64_t dot(const bool *v1, const bool *v2, int32_t n)
compute dot product between v1 and v2 (blas optimized)
Definition: SGVector.h:344
static float64_t * H
Definition: libbmrm.cpp:24
static const double * get_col(uint32_t j)
float64_t * H_buff
Definition: libbmrm.h:61
Class DualLibQPBMSOSVM that uses Bundle Methods for Regularized Risk Minimization algorithms for stru...
float64_t * get_cutting_plane(bmrm_ll *ptr)
Definition: libbmrm.h:116
uint32_t idx
Definition: libbmrm.h:42
#define LIBBMRM_MEMMOVE(x, y, z)
Definition: libbmrm.h:27
static T max(T *vec, int32_t len)
Definition: SGVector.cpp:981
SGVector< float64_t > hist_wdist
bmrm_ll * next
Definition: libbmrm.h:38
void remove_cutting_plane(bmrm_ll **head, bmrm_ll **tail, bool *map, float64_t *icp)
Definition: libbmrm.cpp:56
uint32_t * ACPs
Definition: libbmrm.h:58
SGVector< float64_t > hist_Fd
static float64_t primal_objective(SGVector< float64_t > w, CStructuredModel *model, float64_t lbda)
Definition: SOSVMHelper.cpp:56
virtual int32_t get_dim() const =0
uint32_t find_free_idx(bool *map, uint32_t size)
Definition: libbmrm.h:124
static float64_t average_loss(SGVector< float64_t > w, CStructuredModel *model)
Definition: SOSVMHelper.cpp:85
static const float64_t epsilon
Definition: libbmrm.cpp:22
float64_t cur_time_diff(bool verbose=false)
Definition: Time.cpp:67
#define ASSERT(x)
Definition: SGIO.h:203
#define LIBBMRM_FREE(x)
Definition: libbmrm.h:25
#define LIBBMRM_ABS(A)
Definition: libbmrm.h:29
static const uint32_t QPSolverMaxIter
Definition: libbmrm.cpp:21
bmrm_ll * prev
Definition: libbmrm.h:36
double float64_t
Definition: common.h:48
long double floatmax_t
Definition: common.h:49
class CSOSVMHelper contains helper functions to compute primal objectives, dual objectives, average training losses, duality gaps etc. These values will be recorded to check convergence. This class is inspired by the matlab implementation of the block coordinate Frank-Wolfe SOSVM solver [1].
Definition: SOSVMHelper.h:29
virtual float64_t risk(float64_t *subgrad, float64_t *W, TMultipleCPinfo *info=0, EStructRiskType rtype=N_SLACK_MARGIN_RESCALING)
BmrmStatistics svm_bmrm_solver(CDualLibQPBMSOSVM *machine, float64_t *W, float64_t TolRel, float64_t TolAbs, float64_t _lambda, uint32_t _BufSize, bool cleanICP, uint32_t cleanAfter, float64_t K, uint32_t Tmax, bool verbose)
Definition: libbmrm.cpp:180
SGVector< float64_t > hist_Fp
#define LIBBMRM_MEMCPY(x, y, z)
Definition: libbmrm.h:26
float64_t ** ICPs
Definition: libbmrm.h:55
uint32_t maxCPs
Definition: libbmrm.h:49
Class CStructuredModel that represents the application specific model and contains most of the applic...
#define LIBBMRM_INDEX(ROW, COL, NUM_ROWS)
Definition: libbmrm.h:28
#define SG_UNREF(x)
Definition: SGObject.h:54
#define SG_SDEBUG(...)
Definition: SGIO.h:170
virtual void add_debug_info(float64_t primal, float64_t eff_pass, float64_t train_error, float64_t dual=-1, float64_t dgap=-1)
void add_cutting_plane(bmrm_ll **tail, bool *map, float64_t *A, uint32_t free_idx, float64_t *cp_data, uint32_t dim)
Definition: libbmrm.cpp:27
uint32_t * ICPcounter
Definition: libbmrm.h:52
#define SG_SERROR(...)
Definition: SGIO.h:181
float64_t * address
Definition: libbmrm.h:40
CStructuredModel * get_model() const
void resize_vector(int32_t n)
Definition: SGVector.cpp:307
static float32_t sqrt(float32_t x)
x^0.5
Definition: Math.h:252
#define LIBBMRM_PLUS_INF
Definition: libbmrm.h:22
void clean_icp(ICP_stats *icp_stats, BmrmStatistics &bmrm, bmrm_ll **head, bmrm_ll **tail, float64_t *&Hmat, float64_t *&diag_H, float64_t *&beta, bool *&map, uint32_t cleanAfter, float64_t *&b, uint32_t *&I, uint32_t cp_models)
Definition: libbmrm.cpp:89
static void vec1_plus_scalar_times_vec2(T *vec1, const T scalar, const T *vec2, int32_t n)
x=x+alpha*y
Definition: SGVector.cpp:580
static uint32_t BufSize
Definition: libbmrm.cpp:25

SHOGUN Machine Learning Toolbox - Documentation