SHOGUN  4.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Kernel.cpp
Go to the documentation of this file.
1 /*
2  * EXCEPT FOR THE KERNEL CACHING FUNCTIONS WHICH ARE (W) THORSTEN JOACHIMS
3  * COPYRIGHT (C) 1999 UNIVERSITAET DORTMUND - ALL RIGHTS RESERVED
4  *
5  * this program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Written (W) 1999-2009 Soeren Sonnenburg
11  * Written (W) 1999-2008 Gunnar Raetsch
12  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
13  */
14 
15 #include <shogun/lib/config.h>
16 #include <shogun/lib/common.h>
17 #include <shogun/io/SGIO.h>
18 #include <shogun/io/File.h>
19 #include <shogun/lib/Time.h>
20 #include <shogun/lib/Signal.h>
21 
22 #include <shogun/base/Parallel.h>
23 
24 #include <shogun/kernel/Kernel.h>
27 #include <shogun/base/Parameter.h>
28 
30 
31 #include <string.h>
32 #include <unistd.h>
34 
35 #ifdef HAVE_PTHREAD
36 #include <pthread.h>
37 #endif
38 
39 using namespace shogun;
40 
42 {
43  init();
45 }
46 
47 CKernel::CKernel(int32_t size) : CSGObject()
48 {
49  init();
50 
51  if (size<10)
52  size=10;
53 
54  cache_size=size;
56 }
57 
58 
59 CKernel::CKernel(CFeatures* p_lhs, CFeatures* p_rhs, int32_t size) : CSGObject()
60 {
61  init();
62 
63  if (size<10)
64  size=10;
65 
66  cache_size=size;
67 
69  init(p_lhs, p_rhs);
71 }
72 
74 {
75  if (get_is_initialized())
76  SG_ERROR("Kernel still initialized on destruction.\n")
77 
80 
81  SG_INFO("Kernel deleted (%p).\n", this)
82 }
83 
84 #ifdef USE_SVMLIGHT
85 void CKernel::resize_kernel_cache(KERNELCACHE_IDX size, bool regression_hack)
86 {
87  if (size<10)
88  size=10;
89 
91  cache_size=size;
92 
93  if (has_features() && get_num_vec_lhs())
94  kernel_cache_init(cache_size, regression_hack);
95 }
96 #endif //USE_SVMLIGHT
97 
98 bool CKernel::init(CFeatures* l, CFeatures* r)
99 {
100  /* make sure that features are not deleted if same ones are used */
101  SG_REF(l);
102  SG_REF(r);
103 
104  //make sure features were indeed supplied
105  REQUIRE(l, "CKernel::init(%p, %p): Left hand side features required!\n", l, r)
106  REQUIRE(r, "CKernel::init(%p, %p): Right hand side features required!\n", l, r)
107 
108  //make sure features are compatible
109  if (l->support_compatible_class())
110  {
112  "Right hand side of features (%s) must be compatible with left hand side features (%s)\n",
113  l->get_name(), r->get_name());
114  }
115  else
116  {
118  "Right hand side of features (%s) must be compatible with left hand side features (%s)\n",
119  l->get_name(), r->get_name())
120  }
122 
123  //remove references to previous features
125 
126  //increase reference counts
127  SG_REF(l);
128  if (l==r)
129  lhs_equals_rhs=true;
130  else // l!=r
131  SG_REF(r);
132 
133  lhs=l;
134  rhs=r;
135 
138 
141 
142  /* unref "safety" refs from beginning */
143  SG_UNREF(r);
144  SG_UNREF(l);
145 
146  SG_DEBUG("leaving CKernel::init(%p, %p)\n", l, r)
147  return true;
148 }
149 
151 {
152  SG_REF(n);
153  if (lhs && rhs)
154  n->init(this);
155 
157  normalizer=n;
158 
159  return (normalizer!=NULL);
160 }
161 
163 {
165  return normalizer;
166 }
167 
169 {
170  return normalizer->init(this);
171 }
172 
174 {
176 }
177 
178 #ifdef USE_SVMLIGHT
179 /****************************** Cache handling *******************************/
180 
181 void CKernel::kernel_cache_init(int32_t buffsize, bool regression_hack)
182 {
183  int32_t totdoc=get_num_vec_lhs();
184  if (totdoc<=0)
185  {
186  SG_ERROR("kernel has zero rows: num_lhs=%d num_rhs=%d\n",
188  }
189  uint64_t buffer_size=0;
190  int32_t i;
191 
192  //in regression the additional constraints are made by doubling the training data
193  if (regression_hack)
194  totdoc*=2;
195 
196  buffer_size=((uint64_t) buffsize)*1024*1024/sizeof(KERNELCACHE_ELEM);
197  if (buffer_size>((uint64_t) totdoc)*totdoc)
198  buffer_size=((uint64_t) totdoc)*totdoc;
199 
200  SG_INFO("using a kernel cache of size %lld MB (%lld bytes) for %s Kernel\n", buffer_size*sizeof(KERNELCACHE_ELEM)/1024/1024, buffer_size*sizeof(KERNELCACHE_ELEM), get_name())
201 
202  //make sure it fits in the *signed* KERNELCACHE_IDX type
203  ASSERT(buffer_size < (((uint64_t) 1) << (sizeof(KERNELCACHE_IDX)*8-1)))
204 
205  kernel_cache.index = SG_MALLOC(int32_t, totdoc);
206  kernel_cache.occu = SG_MALLOC(int32_t, totdoc);
207  kernel_cache.lru = SG_MALLOC(int32_t, totdoc);
208  kernel_cache.invindex = SG_MALLOC(int32_t, totdoc);
209  kernel_cache.active2totdoc = SG_MALLOC(int32_t, totdoc);
210  kernel_cache.totdoc2active = SG_MALLOC(int32_t, totdoc);
211  kernel_cache.buffer = SG_MALLOC(KERNELCACHE_ELEM, buffer_size);
212  kernel_cache.buffsize=buffer_size;
213  kernel_cache.max_elems=(int32_t) (kernel_cache.buffsize/totdoc);
214 
215  if(kernel_cache.max_elems>totdoc) {
216  kernel_cache.max_elems=totdoc;
217  }
218 
219  kernel_cache.elems=0; // initialize cache
220  for(i=0;i<totdoc;i++) {
221  kernel_cache.index[i]=-1;
222  kernel_cache.lru[i]=0;
223  }
224  for(i=0;i<totdoc;i++) {
225  kernel_cache.occu[i]=0;
226  kernel_cache.invindex[i]=-1;
227  }
228 
229  kernel_cache.activenum=totdoc;;
230  for(i=0;i<totdoc;i++) {
231  kernel_cache.active2totdoc[i]=i;
232  kernel_cache.totdoc2active[i]=i;
233  }
234 
235  kernel_cache.time=0;
236 }
237 
239  int32_t docnum, int32_t *active2dnum, float64_t *buffer, bool full_line)
240 {
241  int32_t i,j;
242  KERNELCACHE_IDX start;
243 
244  int32_t num_vectors = get_num_vec_lhs();
245  if (docnum>=num_vectors)
246  docnum=2*num_vectors-1-docnum;
247 
248  /* is cached? */
249  if(kernel_cache.index[docnum] != -1)
250  {
251  kernel_cache.lru[kernel_cache.index[docnum]]=kernel_cache.time; /* lru */
252  start=((KERNELCACHE_IDX) kernel_cache.activenum)*kernel_cache.index[docnum];
253 
254  if (full_line)
255  {
256  for(j=0;j<get_num_vec_lhs();j++)
257  {
258  if(kernel_cache.totdoc2active[j] >= 0)
259  buffer[j]=kernel_cache.buffer[start+kernel_cache.totdoc2active[j]];
260  else
261  buffer[j]=(float64_t) kernel(docnum, j);
262  }
263  }
264  else
265  {
266  for(i=0;(j=active2dnum[i])>=0;i++)
267  {
268  if(kernel_cache.totdoc2active[j] >= 0)
269  buffer[j]=kernel_cache.buffer[start+kernel_cache.totdoc2active[j]];
270  else
271  {
272  int32_t k=j;
273  if (k>=num_vectors)
274  k=2*num_vectors-1-k;
275  buffer[j]=(float64_t) kernel(docnum, k);
276  }
277  }
278  }
279  }
280  else
281  {
282  if (full_line)
283  {
284  for(j=0;j<get_num_vec_lhs();j++)
285  buffer[j]=(KERNELCACHE_ELEM) kernel(docnum, j);
286  }
287  else
288  {
289  for(i=0;(j=active2dnum[i])>=0;i++)
290  {
291  int32_t k=j;
292  if (k>=num_vectors)
293  k=2*num_vectors-1-k;
294  buffer[j]=(KERNELCACHE_ELEM) kernel(docnum, k);
295  }
296  }
297  }
298 }
299 
300 
301 // Fills cache for the row m
303 {
304  register int32_t j,k,l;
305  register KERNELCACHE_ELEM *cache;
306 
307  int32_t num_vectors = get_num_vec_lhs();
308 
309  if (m>=num_vectors)
310  m=2*num_vectors-1-m;
311 
312  if(!kernel_cache_check(m)) // not cached yet
313  {
314  cache = kernel_cache_clean_and_malloc(m);
315  if(cache) {
316  l=kernel_cache.totdoc2active[m];
317 
318  for(j=0;j<kernel_cache.activenum;j++) // fill cache
319  {
320  k=kernel_cache.active2totdoc[j];
321 
322  if((kernel_cache.index[k] != -1) && (l != -1) && (k != m)) {
323  cache[j]=kernel_cache.buffer[((KERNELCACHE_IDX) kernel_cache.activenum)
324  *kernel_cache.index[k]+l];
325  }
326  else
327  {
328  if (k>=num_vectors)
329  k=2*num_vectors-1-k;
330 
331  cache[j]=kernel(m, k);
332  }
333  }
334  }
335  else
336  perror("Error: Kernel cache full! => increase cache size");
337  }
338 }
339 
340 
341 void* CKernel::cache_multiple_kernel_row_helper(void* p)
342 {
343  int32_t j,k,l;
344  S_KTHREAD_PARAM* params = (S_KTHREAD_PARAM*) p;
345 
346  for (int32_t i=params->start; i<params->end; i++)
347  {
348  KERNELCACHE_ELEM* cache=params->cache[i];
349  int32_t m = params->uncached_rows[i];
350  l=params->kernel_cache->totdoc2active[m];
351 
352  for(j=0;j<params->kernel_cache->activenum;j++) // fill cache
353  {
354  k=params->kernel_cache->active2totdoc[j];
355 
356  if((params->kernel_cache->index[k] != -1) && (l != -1) && (!params->needs_computation[k])) {
357  cache[j]=params->kernel_cache->buffer[((KERNELCACHE_IDX) params->kernel_cache->activenum)
358  *params->kernel_cache->index[k]+l];
359  }
360  else
361  {
362  if (k>=params->num_vectors)
363  k=2*params->num_vectors-1-k;
364 
365  cache[j]=params->kernel->kernel(m, k);
366  }
367  }
368 
369  //now line m is cached
370  params->needs_computation[m]=0;
371  }
372  return NULL;
373 }
374 
375 // Fills cache for the rows in key
376 void CKernel::cache_multiple_kernel_rows(int32_t* rows, int32_t num_rows)
377 {
378 #ifdef HAVE_PTHREAD
379  int32_t nthreads=parallel->get_num_threads();
380 
381  if (nthreads<2)
382  {
383 #endif
384  for(int32_t i=0;i<num_rows;i++)
385  cache_kernel_row(rows[i]);
386 #ifdef HAVE_PTHREAD
387  }
388  else
389  {
390  // fill up kernel cache
391  int32_t* uncached_rows = SG_MALLOC(int32_t, num_rows);
392  KERNELCACHE_ELEM** cache = SG_MALLOC(KERNELCACHE_ELEM*, num_rows);
393  pthread_t* threads = SG_MALLOC(pthread_t, nthreads-1);
394  S_KTHREAD_PARAM* params = SG_MALLOC(S_KTHREAD_PARAM, nthreads-1);
395  int32_t num_threads=nthreads-1;
396  int32_t num_vec=get_num_vec_lhs();
397  ASSERT(num_vec>0)
398  uint8_t* needs_computation=SG_CALLOC(uint8_t, num_vec);
399 
400  int32_t step=0;
401  int32_t num=0;
402  int32_t end=0;
403 
404  // allocate cachelines if necessary
405  for (int32_t i=0; i<num_rows; i++)
406  {
407  int32_t idx=rows[i];
408  if (idx>=num_vec)
409  idx=2*num_vec-1-idx;
410 
411  if (kernel_cache_check(idx))
412  continue;
413 
414  needs_computation[idx]=1;
415  uncached_rows[num]=idx;
416  cache[num]= kernel_cache_clean_and_malloc(idx);
417 
418  if (!cache[num])
419  SG_ERROR("Kernel cache full! => increase cache size\n")
420 
421  num++;
422  }
423 
424  if (num>0)
425  {
426  step= num/nthreads;
427 
428  if (step<1)
429  {
430  num_threads=num-1;
431  step=1;
432  }
433 
434  for (int32_t t=0; t<num_threads; t++)
435  {
436  params[t].kernel = this;
437  params[t].kernel_cache = &kernel_cache;
438  params[t].cache = cache;
439  params[t].uncached_rows = uncached_rows;
440  params[t].needs_computation = needs_computation;
441  params[t].num_uncached = num;
442  params[t].start = t*step;
443  params[t].end = (t+1)*step;
444  params[t].num_vectors = get_num_vec_lhs();
445  end=params[t].end;
446 
447  int code=pthread_create(&threads[t], NULL,
448  CKernel::cache_multiple_kernel_row_helper, (void*)&params[t]);
449 
450  if (code != 0)
451  {
452  SG_WARNING("Thread creation failed (thread %d of %d) "
453  "with error:'%s'\n",t, num_threads, strerror(code));
454  num_threads=t;
455  end=t*step;
456  break;
457  }
458  }
459  }
460  else
461  num_threads=-1;
462 
463 
464  S_KTHREAD_PARAM last_param;
465  last_param.kernel = this;
466  last_param.kernel_cache = &kernel_cache;
467  last_param.cache = cache;
468  last_param.uncached_rows = uncached_rows;
469  last_param.needs_computation = needs_computation;
470  last_param.start = end;
471  last_param.num_uncached = num;
472  last_param.end = num;
473  last_param.num_vectors = get_num_vec_lhs();
474 
475  cache_multiple_kernel_row_helper(&last_param);
476 
477 
478  for (int32_t t=0; t<num_threads; t++)
479  {
480  if (pthread_join(threads[t], NULL) != 0)
481  SG_WARNING("pthread_join of thread %d/%d failed\n", t, num_threads)
482  }
483 
484  SG_FREE(needs_computation);
485  SG_FREE(params);
486  SG_FREE(threads);
487  SG_FREE(cache);
488  SG_FREE(uncached_rows);
489  }
490 #endif
491 }
492 
493 // remove numshrink columns in the cache
494 // which correspond to examples marked
496  int32_t totdoc, int32_t numshrink, int32_t *after)
497 {
498  ASSERT(totdoc > 0);
499  register int32_t i,j,jj,scount; // 0 in after.
500  KERNELCACHE_IDX from=0,to=0;
501  int32_t *keep;
502 
503  keep=SG_MALLOC(int32_t, totdoc);
504  for(j=0;j<totdoc;j++) {
505  keep[j]=1;
506  }
507  scount=0;
508  for(jj=0;(jj<kernel_cache.activenum) && (scount<numshrink);jj++) {
509  j=kernel_cache.active2totdoc[jj];
510  if(!after[j]) {
511  scount++;
512  keep[j]=0;
513  }
514  }
515 
516  for(i=0;i<kernel_cache.max_elems;i++) {
517  for(jj=0;jj<kernel_cache.activenum;jj++) {
518  j=kernel_cache.active2totdoc[jj];
519  if(!keep[j]) {
520  from++;
521  }
522  else {
523  kernel_cache.buffer[to]=kernel_cache.buffer[from];
524  to++;
525  from++;
526  }
527  }
528  }
529 
530  kernel_cache.activenum=0;
531  for(j=0;j<totdoc;j++) {
532  if((keep[j]) && (kernel_cache.totdoc2active[j] != -1)) {
533  kernel_cache.active2totdoc[kernel_cache.activenum]=j;
534  kernel_cache.totdoc2active[j]=kernel_cache.activenum;
535  kernel_cache.activenum++;
536  }
537  else {
538  kernel_cache.totdoc2active[j]=-1;
539  }
540  }
541 
542  kernel_cache.max_elems= (int32_t) kernel_cache.buffsize;
543 
544  if (kernel_cache.activenum>0)
545  kernel_cache.buffsize/=kernel_cache.activenum;
546 
547  if(kernel_cache.max_elems>totdoc)
548  kernel_cache.max_elems=totdoc;
549 
550  SG_FREE(keep);
551 
552 }
553 
555 {
556  int32_t maxlru=0,k;
557 
558  for(k=0;k<kernel_cache.max_elems;k++) {
559  if(maxlru < kernel_cache.lru[k])
560  maxlru=kernel_cache.lru[k];
561  }
562  for(k=0;k<kernel_cache.max_elems;k++) {
563  kernel_cache.lru[k]-=maxlru;
564  }
565 }
566 
568 {
569  SG_FREE(kernel_cache.index);
570  SG_FREE(kernel_cache.occu);
571  SG_FREE(kernel_cache.lru);
572  SG_FREE(kernel_cache.invindex);
573  SG_FREE(kernel_cache.active2totdoc);
574  SG_FREE(kernel_cache.totdoc2active);
575  SG_FREE(kernel_cache.buffer);
576  memset(&kernel_cache, 0x0, sizeof(KERNEL_CACHE));
577 }
578 
579 int32_t CKernel::kernel_cache_malloc()
580 {
581  int32_t i;
582 
584  for(i=0;i<kernel_cache.max_elems;i++) {
585  if(!kernel_cache.occu[i]) {
586  kernel_cache.occu[i]=1;
587  kernel_cache.elems++;
588  return(i);
589  }
590  }
591  }
592  return(-1);
593 }
594 
595 void CKernel::kernel_cache_free(int32_t cacheidx)
596 {
597  kernel_cache.occu[cacheidx]=0;
598  kernel_cache.elems--;
599 }
600 
601 // remove least recently used cache
602 // element
603 int32_t CKernel::kernel_cache_free_lru()
604 {
605  register int32_t k,least_elem=-1,least_time;
606 
607  least_time=kernel_cache.time+1;
608  for(k=0;k<kernel_cache.max_elems;k++) {
609  if(kernel_cache.invindex[k] != -1) {
610  if(kernel_cache.lru[k]<least_time) {
611  least_time=kernel_cache.lru[k];
612  least_elem=k;
613  }
614  }
615  }
616 
617  if(least_elem != -1) {
618  kernel_cache_free(least_elem);
619  kernel_cache.index[kernel_cache.invindex[least_elem]]=-1;
620  kernel_cache.invindex[least_elem]=-1;
621  return(1);
622  }
623  return(0);
624 }
625 
626 // Get a free cache entry. In case cache is full, the lru
627 // element is removed.
628 KERNELCACHE_ELEM* CKernel::kernel_cache_clean_and_malloc(int32_t cacheidx)
629 {
630  int32_t result;
631  if((result = kernel_cache_malloc()) == -1) {
632  if(kernel_cache_free_lru()) {
633  result = kernel_cache_malloc();
634  }
635  }
636  kernel_cache.index[cacheidx]=result;
637  if(result == -1) {
638  return(0);
639  }
640  kernel_cache.invindex[result]=cacheidx;
641  kernel_cache.lru[kernel_cache.index[cacheidx]]=kernel_cache.time; // lru
642  return &kernel_cache.buffer[((KERNELCACHE_IDX) kernel_cache.activenum)*kernel_cache.index[cacheidx]];
643 }
644 #endif //USE_SVMLIGHT
645 
646 void CKernel::load(CFile* loader)
647 {
650 }
651 
652 void CKernel::save(CFile* writer)
653 {
654  SGMatrix<float64_t> k_matrix=get_kernel_matrix<float64_t>();
656  writer->set_matrix(k_matrix.matrix, k_matrix.num_rows, k_matrix.num_cols);
658 }
659 
661 {
662  SG_DEBUG("entering CKernel::remove_lhs_and_rhs\n")
663  if (rhs!=lhs)
664  SG_UNREF(rhs);
665  rhs = NULL;
666  num_rhs=0;
667 
668  SG_UNREF(lhs);
669  lhs = NULL;
670  num_lhs=0;
671  lhs_equals_rhs=false;
672 
673 #ifdef USE_SVMLIGHT
674  cache_reset();
675 #endif //USE_SVMLIGHT
676  SG_DEBUG("leaving CKernel::remove_lhs_and_rhs\n")
677 }
678 
680 {
681  if (rhs==lhs)
682  rhs=NULL;
683  SG_UNREF(lhs);
684  lhs = NULL;
685  num_lhs=0;
686  lhs_equals_rhs=false;
687 #ifdef USE_SVMLIGHT
688  cache_reset();
689 #endif //USE_SVMLIGHT
690 }
691 
694 {
695  if (rhs!=lhs)
696  SG_UNREF(rhs);
697  rhs = NULL;
698  num_rhs=0;
699  lhs_equals_rhs=false;
700 
701 #ifdef USE_SVMLIGHT
702  cache_reset();
703 #endif //USE_SVMLIGHT
704 }
705 
706 #define ENUM_CASE(n) case n: SG_INFO(#n " ") break;
707 
709 {
710  SG_INFO("%p - \"%s\" weight=%1.2f OPT:%s", this, get_name(),
712  get_optimization_type()==FASTBUTMEMHUNGRY ? "FASTBUTMEMHUNGRY" :
713  "SLOWBUTMEMEFFICIENT");
714 
715  switch (get_kernel_type())
716  {
779  }
780 
781  switch (get_feature_class())
782  {
793  ENUM_CASE(C_WD)
805  }
806 
807  switch (get_feature_type())
808  {
823  }
824  SG_INFO("\n")
825 }
826 #undef ENUM_CASE
827 
829  int32_t count, int32_t *IDX, float64_t * weights)
830 {
831  SG_ERROR("kernel does not support linadd optimization\n")
832  return false ;
833 }
834 
836 {
837  SG_ERROR("kernel does not support linadd optimization\n")
838  return false;
839 }
840 
842 {
843  SG_ERROR("kernel does not support linadd optimization\n")
844  return 0;
845 }
846 
848  int32_t num_vec, int32_t* vec_idx, float64_t* target, int32_t num_suppvec,
849  int32_t* IDX, float64_t* weights, float64_t factor)
850 {
851  SG_ERROR("kernel does not support batch computation\n")
852 }
853 
854 void CKernel::add_to_normal(int32_t vector_idx, float64_t weight)
855 {
856  SG_ERROR("kernel does not support linadd optimization, add_to_normal not implemented\n")
857 }
858 
860 {
861  SG_ERROR("kernel does not support linadd optimization, clear_normal not implemented\n")
862 }
863 
865 {
866  return 1;
867 }
868 
870  int32_t vector_idx, float64_t * subkernel_contrib)
871 {
872  SG_ERROR("kernel compute_by_subkernel not implemented\n")
873 }
874 
875 const float64_t* CKernel::get_subkernel_weights(int32_t &num_weights)
876 {
877  num_weights=1 ;
878  return &combined_kernel_weight ;
879 }
880 
882 {
883  int num_weights = 1;
884  const float64_t* weight = get_subkernel_weights(num_weights);
885  return SGVector<float64_t>(const_cast<float64_t*>(weight),1,false);
886 }
887 
889 {
890  ASSERT(weights.vector)
891  if (weights.vlen!=1)
892  SG_ERROR("number of subkernel weights should be one ...\n")
893 
894  combined_kernel_weight = weights.vector[0] ;
895 }
896 
898 {
899  if (kernel)
900  {
901  CKernel* casted=dynamic_cast<CKernel*>(kernel);
902  REQUIRE(casted, "CKernel::obtain_from_generic(): Error, provided object"
903  " of class \"%s\" is not a subclass of CKernel!\n",
904  kernel->get_name());
905  return casted;
906  }
907  else
908  return NULL;
909 }
910 
912 {
913  int32_t num_suppvec=svm->get_num_support_vectors();
914  int32_t* sv_idx=SG_MALLOC(int32_t, num_suppvec);
915  float64_t* sv_weight=SG_MALLOC(float64_t, num_suppvec);
916 
917  for (int32_t i=0; i<num_suppvec; i++)
918  {
919  sv_idx[i] = svm->get_support_vector(i);
920  sv_weight[i] = svm->get_alpha(i);
921  }
922  bool ret = init_optimization(num_suppvec, sv_idx, sv_weight);
923 
924  SG_FREE(sv_idx);
925  SG_FREE(sv_weight);
926  return ret;
927 }
928 
930 {
932  if (lhs_equals_rhs)
933  rhs=lhs;
934 }
935 
937 {
939 
940  if (lhs_equals_rhs)
941  rhs=NULL;
942 }
943 
945 {
947 
948  if (lhs_equals_rhs)
949  rhs=lhs;
950 }
951 
953  SG_ADD(&cache_size, "cache_size",
954  "Cache size in MB.", MS_NOT_AVAILABLE);
955  SG_ADD((CSGObject**) &lhs, "lhs",
956  "Feature vectors to occur on left hand side.", MS_NOT_AVAILABLE);
957  SG_ADD((CSGObject**) &rhs, "rhs",
958  "Feature vectors to occur on right hand side.", MS_NOT_AVAILABLE);
959  SG_ADD(&lhs_equals_rhs, "lhs_equals_rhs",
960  "If features on lhs are the same as on rhs.", MS_NOT_AVAILABLE);
961  SG_ADD(&num_lhs, "num_lhs", "Number of feature vectors on left hand side.",
963  SG_ADD(&num_rhs, "num_rhs", "Number of feature vectors on right hand side.",
965  SG_ADD(&combined_kernel_weight, "combined_kernel_weight",
966  "Combined kernel weight.", MS_AVAILABLE);
967  SG_ADD(&optimization_initialized, "optimization_initialized",
968  "Optimization is initialized.", MS_NOT_AVAILABLE);
969  SG_ADD((machine_int_t*) &opt_type, "opt_type",
970  "Optimization type.", MS_NOT_AVAILABLE);
971  SG_ADD(&properties, "properties", "Kernel properties.", MS_NOT_AVAILABLE);
972  SG_ADD((CSGObject**) &normalizer, "normalizer", "Normalize the kernel.",
973  MS_AVAILABLE);
974 }
975 
976 
977 void CKernel::init()
978 {
979  cache_size=10;
980  kernel_matrix=NULL;
981  lhs=NULL;
982  rhs=NULL;
983  num_lhs=0;
984  num_rhs=0;
985  lhs_equals_rhs=false;
990  normalizer=NULL;
991 
992 #ifdef USE_SVMLIGHT
993  memset(&kernel_cache, 0x0, sizeof(KERNEL_CACHE));
994 #endif //USE_SVMLIGHT
995 
997 }
998 
999 namespace shogun
1000 {
1002 template <class T> struct K_THREAD_PARAM
1003 {
1007  int32_t start;
1009  int32_t end;
1011  int64_t total_start;
1013  int64_t total_end;
1015  int32_t m;
1017  int32_t n;
1023  bool verbose;
1024 };
1025 }
1026 
1028  bool no_diag)
1029 {
1030  SG_DEBUG("Entering\n");
1031 
1032  REQUIRE(has_features(), "No features assigned to kernel\n")
1033  REQUIRE(lhs_equals_rhs, "The kernel matrix is not symmetric!\n")
1034  REQUIRE(block_begin>=0 && block_begin<num_rhs,
1035  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
1036  REQUIRE(block_begin+block_size<=num_rhs,
1037  "Invalid block size (%d) at starting index (%d, %d)! "
1038  "Please use smaller blocks!", block_size, block_begin, block_begin)
1039  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
1040 
1041  float64_t sum=0.0;
1042 
1043  // since the block is symmetric with main diagonal inside, we can save half
1044  // the computation with using only the upper triangular part.
1045  // this can be done in parallel
1046 #pragma omp parallel for
1047  for (index_t i=0; i<block_size; ++i)
1048  {
1049  // compute the kernel values on the upper triangular part of the kernel
1050  // matrix and compute sum on the fly
1051  for (index_t j=i+1; j<block_size; ++j)
1052  {
1053  float64_t k=kernel(i+block_begin, j+block_begin);
1054 #pragma omp atomic
1055  sum+=k;
1056  }
1057  }
1058 
1059  // the actual sum would be twice of what we computed
1060  sum*=2;
1061 
1062  // add the diagonal elements if required - keeping this check
1063  // outside of the loop to save cycles
1064  if (!no_diag)
1065  {
1066 #pragma omp parallel for
1067  for (index_t i=0; i<block_size; ++i)
1068  {
1069  float64_t diag=kernel(i+block_begin, i+block_begin);
1070 #pragma omp atomic
1071  sum+=diag;
1072  }
1073  }
1074 
1075  SG_DEBUG("Leaving\n");
1076 
1077  return sum;
1078 }
1079 
1080 float64_t CKernel::sum_block(index_t block_begin_row, index_t block_begin_col,
1081  index_t block_size_row, index_t block_size_col, bool no_diag)
1082 {
1083  SG_DEBUG("Entering\n");
1084 
1085  REQUIRE(has_features(), "No features assigned to kernel\n")
1086  REQUIRE(block_begin_row>=0 && block_begin_row<num_lhs &&
1087  block_begin_col>=0 && block_begin_col<num_rhs,
1088  "Invalid block begin index (%d, %d)!\n",
1089  block_begin_row, block_begin_col)
1090  REQUIRE(block_begin_row+block_size_row<=num_lhs &&
1091  block_begin_col+block_size_col<=num_rhs,
1092  "Invalid block size (%d, %d) at starting index (%d, %d)! "
1093  "Please use smaller blocks!", block_size_row, block_size_col,
1094  block_begin_row, block_begin_col)
1095  REQUIRE(block_size_row>=1 && block_size_col>=1,
1096  "Invalid block size (%d, %d)!\n", block_size_row, block_size_col)
1097 
1098  // check if removal of diagonal is required/valid
1099  if (no_diag && block_size_row!=block_size_col)
1100  {
1101  SG_WARNING("Not removing the main diagonal since block is not square!\n");
1102  no_diag=false;
1103  }
1104 
1105  float64_t sum=0.0;
1106 
1107  // this can be done in parallel for the rows/cols
1108 #pragma omp parallel for
1109  for (index_t i=0; i<block_size_row; ++i)
1110  {
1111  // compute the kernel values and compute sum on the fly
1112  for (index_t j=0; j<block_size_col; ++j)
1113  {
1114  float64_t k=no_diag && i==j ? 0 :
1115  kernel(i+block_begin_row, j+block_begin_col);
1116 #pragma omp atomic
1117  sum+=k;
1118  }
1119  }
1120 
1121  SG_DEBUG("Leaving\n");
1122 
1123  return sum;
1124 }
1125 
1127  index_t block_size, bool no_diag)
1128 {
1129  SG_DEBUG("Entering\n");
1130 
1131  REQUIRE(has_features(), "No features assigned to kernel\n")
1132  REQUIRE(lhs_equals_rhs, "The kernel matrix is not symmetric!\n")
1133  REQUIRE(block_begin>=0 && block_begin<num_rhs,
1134  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
1135  REQUIRE(block_begin+block_size<=num_rhs,
1136  "Invalid block size (%d) at starting index (%d, %d)! "
1137  "Please use smaller blocks!", block_size, block_begin, block_begin)
1138  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
1139 
1140  // initialize the vector that accumulates the row/col-wise sum on the go
1141  SGVector<float64_t> row_sum(block_size);
1142  row_sum.set_const(0.0);
1143 
1144  // since the block is symmetric with main diagonal inside, we can save half
1145  // the computation with using only the upper triangular part.
1146  // this can be done in parallel for the rows/cols
1147 #pragma omp parallel for
1148  for (index_t i=0; i<block_size; ++i)
1149  {
1150  // compute the kernel values on the upper triangular part of the kernel
1151  // matrix and compute row-wise sum on the fly
1152  for (index_t j=i+1; j<block_size; ++j)
1153  {
1154  float64_t k=kernel(i+block_begin, j+block_begin);
1155 #pragma omp critical
1156  {
1157  row_sum[i]+=k;
1158  row_sum[j]+=k;
1159  }
1160  }
1161  }
1162 
1163  // add the diagonal elements if required - keeping this check
1164  // outside of the loop to save cycles
1165  if (!no_diag)
1166  {
1167 #pragma omp parallel for
1168  for (index_t i=0; i<block_size; ++i)
1169  {
1170  float64_t diag=kernel(i+block_begin, i+block_begin);
1171  row_sum[i]+=diag;
1172  }
1173  }
1174 
1175  SG_DEBUG("Leaving\n");
1176 
1177  return row_sum;
1178 }
1179 
1181  block_begin, index_t block_size, bool no_diag)
1182 {
1183  SG_DEBUG("Entering\n");
1184 
1185  REQUIRE(has_features(), "No features assigned to kernel\n")
1186  REQUIRE(lhs_equals_rhs, "The kernel matrix is not symmetric!\n")
1187  REQUIRE(block_begin>=0 && block_begin<num_rhs,
1188  "Invalid block begin index (%d, %d)!\n", block_begin, block_begin)
1189  REQUIRE(block_begin+block_size<=num_rhs,
1190  "Invalid block size (%d) at starting index (%d, %d)! "
1191  "Please use smaller blocks!", block_size, block_begin, block_begin)
1192  REQUIRE(block_size>=1, "Invalid block size (%d)!\n", block_size)
1193 
1194  // initialize the matrix that accumulates the row/col-wise sum on the go
1195  // the first column stores the sum of kernel values
1196  // the second column stores the sum of squared kernel values
1197  SGMatrix<float64_t> row_sum(block_size, 2);
1198  row_sum.set_const(0.0);
1199 
1200  // since the block is symmetric with main diagonal inside, we can save half
1201  // the computation with using only the upper triangular part
1202  // this can be done in parallel for the rows/cols
1203 #pragma omp parallel for
1204  for (index_t i=0; i<block_size; ++i)
1205  {
1206  // compute the kernel values on the upper triangular part of the kernel
1207  // matrix and compute row-wise sum and squared sum on the fly
1208  for (index_t j=i+1; j<block_size; ++j)
1209  {
1210  float64_t k=kernel(i+block_begin, j+block_begin);
1211 #pragma omp critical
1212  {
1213  row_sum(i, 0)+=k;
1214  row_sum(j, 0)+=k;
1215  row_sum(i, 1)+=k*k;
1216  row_sum(j, 1)+=k*k;
1217  }
1218  }
1219  }
1220 
1221  // add the diagonal elements if required - keeping this check
1222  // outside of the loop to save cycles
1223  if (!no_diag)
1224  {
1225 #pragma omp parallel for
1226  for (index_t i=0; i<block_size; ++i)
1227  {
1228  float64_t diag=kernel(i+block_begin, i+block_begin);
1229  row_sum(i, 0)+=diag;
1230  row_sum(i, 1)+=diag*diag;
1231  }
1232  }
1233 
1234  SG_DEBUG("Leaving\n");
1235 
1236  return row_sum;
1237 }
1238 
1240  index_t block_begin_col, index_t block_size_row,
1241  index_t block_size_col, bool no_diag)
1242 {
1243  SG_DEBUG("Entering\n");
1244 
1245  REQUIRE(has_features(), "No features assigned to kernel\n")
1246  REQUIRE(block_begin_row>=0 && block_begin_row<num_lhs &&
1247  block_begin_col>=0 && block_begin_col<num_rhs,
1248  "Invalid block begin index (%d, %d)!\n",
1249  block_begin_row, block_begin_col)
1250  REQUIRE(block_begin_row+block_size_row<=num_lhs &&
1251  block_begin_col+block_size_col<=num_rhs,
1252  "Invalid block size (%d, %d) at starting index (%d, %d)! "
1253  "Please use smaller blocks!", block_size_row, block_size_col,
1254  block_begin_row, block_begin_col)
1255  REQUIRE(block_size_row>=1 && block_size_col>=1,
1256  "Invalid block size (%d, %d)!\n", block_size_row, block_size_col)
1257 
1258  // check if removal of diagonal is required/valid
1259  if (no_diag && block_size_row!=block_size_col)
1260  {
1261  SG_WARNING("Not removing the main diagonal since block is not square!\n");
1262  no_diag=false;
1263  }
1264 
1265  // initialize the vector that accumulates the row/col-wise sum on the go
1266  // the first block_size_row entries store the row-wise sum of kernel values
1267  // the nextt block_size_col entries store the col-wise sum of kernel values
1268  SGVector<float64_t> sum(block_size_row+block_size_col);
1269  sum.set_const(0.0);
1270 
1271  // this can be done in parallel for the rows/cols
1272 #pragma omp parallel for
1273  for (index_t i=0; i<block_size_row; ++i)
1274  {
1275  // compute the kernel values and compute sum on the fly
1276  for (index_t j=0; j<block_size_col; ++j)
1277  {
1278  float64_t k=no_diag && i==j ? 0 :
1279  kernel(i+block_begin_row, j+block_begin_col);
1280 #pragma omp critical
1281  {
1282  sum[i]+=k;
1283  sum[j+block_size_row]+=k;
1284  }
1285  }
1286  }
1287 
1288  SG_DEBUG("Leaving\n");
1289 
1290  return sum;
1291 }
1292 
1293 template <class T> void* CKernel::get_kernel_matrix_helper(void* p)
1294 {
1295  K_THREAD_PARAM<T>* params= (K_THREAD_PARAM<T>*) p;
1296  int32_t i_start=params->start;
1297  int32_t i_end=params->end;
1298  CKernel* k=params->kernel;
1299  T* result=params->result;
1300  bool symmetric=params->symmetric;
1301  int32_t n=params->n;
1302  int32_t m=params->m;
1303  bool verbose=params->verbose;
1304  int64_t total_start=params->total_start;
1305  int64_t total_end=params->total_end;
1306  int64_t total=total_start;
1307 
1308  for (int32_t i=i_start; i<i_end; i++)
1309  {
1310  int32_t j_start=0;
1311 
1312  if (symmetric)
1313  j_start=i;
1314 
1315  for (int32_t j=j_start; j<n; j++)
1316  {
1317  float64_t v=k->kernel(i,j);
1318  result[i+j*m]=v;
1319 
1320  if (symmetric && i!=j)
1321  result[j+i*m]=v;
1322 
1323  if (verbose)
1324  {
1325  total++;
1326 
1327  if (symmetric && i!=j)
1328  total++;
1329 
1330  if (total%100 == 0)
1331  SG_OBJ_PROGRESS(k, total, total_start, total_end)
1332 
1334  break;
1335  }
1336  }
1337 
1338  }
1339 
1340  return NULL;
1341 }
1342 
1343 template <class T>
1345 {
1346  T* result = NULL;
1347 
1348  REQUIRE(has_features(), "no features assigned to kernel\n")
1349 
1350  int32_t m=get_num_vec_lhs();
1351  int32_t n=get_num_vec_rhs();
1352 
1353  int64_t total_num = int64_t(m)*n;
1354 
1355  // if lhs == rhs and sizes match assume k(i,j)=k(j,i)
1356  bool symmetric= (lhs && lhs==rhs && m==n);
1357 
1358  SG_DEBUG("returning kernel matrix of size %dx%d\n", m, n)
1359 
1360  result=SG_MALLOC(T, total_num);
1361 
1362  int32_t num_threads=parallel->get_num_threads();
1363  if (num_threads < 2)
1364  {
1365  K_THREAD_PARAM<T> params;
1366  params.kernel=this;
1367  params.result=result;
1368  params.start=0;
1369  params.end=m;
1370  params.total_start=0;
1371  params.total_end=total_num;
1372  params.n=n;
1373  params.m=m;
1374  params.symmetric=symmetric;
1375  params.verbose=true;
1376  get_kernel_matrix_helper<T>((void*) &params);
1377  }
1378  else
1379  {
1380  pthread_t* threads = SG_MALLOC(pthread_t, num_threads-1);
1381  K_THREAD_PARAM<T>* params = SG_MALLOC(K_THREAD_PARAM<T>, num_threads);
1382  int64_t step= total_num/num_threads;
1383 
1384  int32_t t;
1385 
1386  num_threads--;
1387  for (t=0; t<num_threads; t++)
1388  {
1389  params[t].kernel = this;
1390  params[t].result = result;
1391  params[t].start = compute_row_start(t*step, n, symmetric);
1392  params[t].end = compute_row_start((t+1)*step, n, symmetric);
1393  params[t].total_start=t*step;
1394  params[t].total_end=(t+1)*step;
1395  params[t].n=n;
1396  params[t].m=m;
1397  params[t].symmetric=symmetric;
1398  params[t].verbose=false;
1399 
1400  int code=pthread_create(&threads[t], NULL,
1401  CKernel::get_kernel_matrix_helper<T>, (void*)&params[t]);
1402 
1403  if (code != 0)
1404  {
1405  SG_WARNING("Thread creation failed (thread %d of %d) "
1406  "with error:'%s'\n",t, num_threads, strerror(code));
1407  num_threads=t;
1408  break;
1409  }
1410  }
1411 
1412  params[t].kernel = this;
1413  params[t].result = result;
1414  params[t].start = compute_row_start(t*step, n, symmetric);
1415  params[t].end = m;
1416  params[t].total_start=t*step;
1417  params[t].total_end=total_num;
1418  params[t].n=n;
1419  params[t].m=m;
1420  params[t].symmetric=symmetric;
1421  params[t].verbose=true;
1422  get_kernel_matrix_helper<T>(&params[t]);
1423 
1424  for (t=0; t<num_threads; t++)
1425  {
1426  if (pthread_join(threads[t], NULL) != 0)
1427  SG_WARNING("pthread_join of thread %d/%d failed\n", t, num_threads)
1428  }
1429 
1430  SG_FREE(params);
1431  SG_FREE(threads);
1432  }
1433 
1434  SG_DONE()
1435 
1436  return SGMatrix<T>(result,m,n,true);
1437 }
1438 
1439 
1440 template SGMatrix<float64_t> CKernel::get_kernel_matrix<float64_t>();
1441 template SGMatrix<float32_t> CKernel::get_kernel_matrix<float32_t>();
1442 
1443 template void* CKernel::get_kernel_matrix_helper<float64_t>(void* p);
1444 template void* CKernel::get_kernel_matrix_helper<float32_t>(void* p);
1445 
virtual void clear_normal()
Definition: Kernel.cpp:859
virtual const char * get_name() const =0
virtual void load_serializable_post()
Definition: Kernel.cpp:929
virtual bool init(CFeatures *lhs, CFeatures *rhs)
Definition: Kernel.cpp:98
virtual bool support_compatible_class() const
Definition: Features.h:323
int32_t compute_row_start(int64_t offs, int32_t n, bool symmetric)
Definition: Kernel.h:920
#define SG_INFO(...)
Definition: SGIO.h:118
virtual void cleanup()
Definition: Kernel.cpp:173
#define SG_RESET_LOCALE
Definition: SGIO.h:86
#define SG_DONE()
Definition: SGIO.h:157
virtual void set_matrix(const bool *matrix, int32_t num_feat, int32_t num_vec)
Definition: File.cpp:126
virtual void compute_by_subkernel(int32_t vector_idx, float64_t *subkernel_contrib)
Definition: Kernel.cpp:869
void cache_multiple_kernel_rows(int32_t *key, int32_t varnum)
Definition: Kernel.cpp:376
virtual bool get_feature_class_compatibility(EFeatureClass rhs) const
Definition: Features.cpp:355
int32_t get_num_threads() const
Definition: Parallel.cpp:78
int32_t index_t
Definition: common.h:62
int32_t num_rhs
number of feature vectors on right hand side
Definition: Kernel.h:1070
static void * get_kernel_matrix_helper(void *p)
Definition: Kernel.cpp:1293
Class ShogunException defines an exception which is thrown whenever an error inside of shogun occurs...
virtual bool set_normalizer(CKernelNormalizer *normalizer)
Definition: Kernel.cpp:150
virtual float64_t sum_block(index_t block_begin_row, index_t block_begin_col, index_t block_size_row, index_t block_size_col, bool no_diag=false)
Definition: Kernel.cpp:1080
virtual int32_t get_num_vectors() const =0
virtual void save_serializable_pre()
Definition: SGObject.cpp:464
#define SG_ERROR(...)
Definition: SGIO.h:129
void cache_reset()
Definition: Kernel.h:603
#define REQUIRE(x,...)
Definition: SGIO.h:206
virtual bool delete_optimization()
Definition: Kernel.cpp:835
int64_t KERNELCACHE_IDX
Definition: Kernel.h:46
int32_t kernel_cache_space_available()
Definition: Kernel.h:699
index_t num_cols
Definition: SGMatrix.h:376
float64_t kernel(int32_t idx_a, int32_t idx_b)
Definition: Kernel.h:207
#define ENUM_CASE(n)
Definition: Kernel.cpp:706
uint64_t properties
Definition: Kernel.h:1083
Parallel * parallel
Definition: SGObject.h:540
virtual void remove_rhs()
takes all necessary steps if the rhs is removed from kernel
Definition: Kernel.cpp:693
virtual int32_t get_num_vec_lhs()
Definition: Kernel.h:517
SGMatrix< float64_t > get_kernel_matrix()
Definition: Kernel.h:220
#define SG_REF(x)
Definition: SGObject.h:54
#define SG_SET_LOCALE_C
Definition: SGIO.h:85
int32_t cache_size
cache_size in MB
Definition: Kernel.h:1048
index_t num_rows
Definition: SGMatrix.h:374
void kernel_cache_shrink(int32_t totdoc, int32_t num_shrink, int32_t *after)
Definition: Kernel.cpp:495
bool get_is_initialized()
Definition: Kernel.h:754
virtual SGMatrix< float64_t > row_wise_sum_squared_sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
Definition: Kernel.cpp:1180
float64_t combined_kernel_weight
Definition: Kernel.h:1073
virtual void register_params()
Definition: Kernel.cpp:952
void save(CFile *writer)
Definition: Kernel.cpp:652
virtual void remove_lhs_and_rhs()
Definition: Kernel.cpp:660
index_t vlen
Definition: SGVector.h:494
virtual CKernelNormalizer * get_normalizer()
Definition: Kernel.cpp:162
#define ASSERT(x)
Definition: SGIO.h:201
Class SGObject is the base class of all shogun objects.
Definition: SGObject.h:115
virtual SGVector< float64_t > row_col_wise_sum_block(index_t block_begin_row, index_t block_begin_col, index_t block_size_row, index_t block_size_col, bool no_diag=false)
Definition: Kernel.cpp:1239
void cache_kernel_row(int32_t x)
Definition: Kernel.cpp:302
#define SG_OBJ_PROGRESS(o,...)
Definition: SGIO.h:147
virtual float64_t sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
Definition: Kernel.cpp:1027
virtual SGVector< float64_t > get_subkernel_weights()
Definition: Kernel.cpp:881
double float64_t
Definition: common.h:50
KERNEL_CACHE kernel_cache
kernel cache
Definition: Kernel.h:1052
virtual EFeatureType get_feature_type()=0
KERNELCACHE_ELEM * kernel_matrix
Definition: Kernel.h:1057
A File access base class.
Definition: File.h:34
virtual void save_serializable_post()
Definition: Kernel.cpp:944
virtual float64_t compute_optimized(int32_t vector_idx)
Definition: Kernel.cpp:841
EOptimizationType get_optimization_type()
Definition: Kernel.h:742
virtual void save_serializable_post()
Definition: SGObject.cpp:469
void list_kernel()
Definition: Kernel.cpp:708
float64_t get_alpha(int32_t idx)
float64_t get_combined_kernel_weight()
Definition: Kernel.h:803
virtual SGVector< float64_t > row_wise_sum_symmetric_block(index_t block_begin, index_t block_size, bool no_diag=true)
Definition: Kernel.cpp:1126
virtual EFeatureClass get_feature_class() const =0
Identity Kernel Normalization, i.e. no normalization is applied.
int32_t num_lhs
number of feature vectors on left hand side
Definition: Kernel.h:1068
The class Kernel Normalizer defines a function to post-process kernel values.
int32_t get_support_vector(int32_t idx)
static bool cancel_computations()
Definition: Signal.h:86
virtual int32_t get_num_vec_rhs()
Definition: Kernel.h:526
virtual void set_subkernel_weights(SGVector< float64_t > weights)
Definition: Kernel.cpp:888
virtual bool init_normalizer()
Definition: Kernel.cpp:168
bool optimization_initialized
Definition: Kernel.h:1076
EOptimizationType opt_type
Definition: Kernel.h:1080
void load(CFile *loader)
Definition: Kernel.cpp:646
virtual void load_serializable_post()
Definition: SGObject.cpp:459
CFeatures * rhs
feature vectors to occur on right hand side
Definition: Kernel.h:1062
static CKernel * obtain_from_generic(CSGObject *kernel)
Definition: Kernel.cpp:897
#define SG_UNREF(x)
Definition: SGObject.h:55
#define SG_DEBUG(...)
Definition: SGIO.h:107
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
virtual bool init(CKernel *k)=0
virtual void compute_batch(int32_t num_vec, int32_t *vec_idx, float64_t *target, int32_t num_suppvec, int32_t *IDX, float64_t *alphas, float64_t factor=1.0)
Definition: Kernel.cpp:847
bool lhs_equals_rhs
lhs
Definition: Kernel.h:1065
int machine_int_t
Definition: common.h:59
virtual EKernelType get_kernel_type()=0
virtual bool init_optimization(int32_t count, int32_t *IDX, float64_t *weights)
Definition: Kernel.cpp:828
CFeatures * lhs
feature vectors to occur on left hand side
Definition: Kernel.h:1060
The class Features is the base class of all feature objects.
Definition: Features.h:68
virtual void save_serializable_pre()
Definition: Kernel.cpp:936
void kernel_cache_cleanup()
Definition: Kernel.cpp:567
virtual void remove_lhs()
Definition: Kernel.cpp:679
int32_t kernel_cache_check(int32_t cacheidx)
Definition: Kernel.h:690
virtual int32_t get_num_subkernels()
Definition: Kernel.cpp:864
bool init_optimization_svm(CSVM *svm)
Definition: Kernel.cpp:911
A generic Support Vector Machine Interface.
Definition: SVM.h:49
void kernel_cache_reset_lru()
Definition: Kernel.cpp:554
The Kernel base class.
Definition: Kernel.h:159
CKernelNormalizer * normalizer
Definition: Kernel.h:1087
virtual SGVector< float64_t > get_kernel_row(int32_t i)
Definition: Kernel.h:280
#define SG_WARNING(...)
Definition: SGIO.h:128
#define SG_ADD(...)
Definition: SGObject.h:84
virtual bool has_features()
Definition: Kernel.h:535
void kernel_cache_init(int32_t size, bool regression_hack=false)
Definition: Kernel.cpp:181
virtual ~CKernel()
Definition: Kernel.cpp:73
virtual void add_to_normal(int32_t vector_idx, float64_t weight)
Definition: Kernel.cpp:854
void set_const(T const_elem)
Definition: SGMatrix.cpp:129
float64_t KERNELCACHE_ELEM
Definition: Kernel.h:35
void set_const(T const_elem)
Definition: SGVector.cpp:150
void resize_kernel_cache(KERNELCACHE_IDX size, bool regression_hack=false)
Definition: Kernel.cpp:85
virtual EFeatureType get_feature_type() const =0
virtual EFeatureClass get_feature_class()=0

SHOGUN Machine Learning Toolbox - Documentation