SHOGUN v0.9.3
Kernel.cpp
Go to the documentation of this file.
00001 /*
00002  * EXCEPT FOR THE KERNEL CACHING FUNCTIONS WHICH ARE (W) THORSTEN JOACHIMS
00003  * COPYRIGHT (C) 1999  UNIVERSITAET DORTMUND - ALL RIGHTS RESERVED
00004  *
00005  * this program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 3 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * Written (W) 1999-2009 Soeren Sonnenburg
00011  * Written (W) 1999-2008 Gunnar Raetsch
00012  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00013  */
00014 
00015 #include "lib/config.h"
00016 #include "lib/common.h"
00017 #include "lib/io.h"
00018 #include "lib/File.h"
00019 #include "lib/Time.h"
00020 #include "lib/Signal.h"
00021 
00022 #include "base/Parallel.h"
00023 
00024 #include "kernel/Kernel.h"
00025 #include "kernel/IdentityKernelNormalizer.h"
00026 #include "features/Features.h"
00027 
00028 #include "classifier/svm/SVM.h"
00029 
00030 #include <string.h>
00031 #include <unistd.h>
00032 #include <math.h>
00033 
00034 #ifndef WIN32
00035 #include <pthread.h>
00036 #endif
00037 
00038 
00039 #ifdef HAVE_BOOST_SERIALIZATION
00040 #include <boost/serialization/export.hpp>
00041 BOOST_CLASS_EXPORT(shogun::CKernel);
00042 #endif //HAVE_BOOST_SERIALIZATION
00043 
00044 
00045 using namespace shogun;
00046 
00047 CKernel::CKernel()
00048 : CSGObject(), cache_size(10), kernel_matrix(NULL), lhs(NULL),
00049     rhs(NULL), num_lhs(0), num_rhs(0), combined_kernel_weight(1),
00050     optimization_initialized(false), opt_type(FASTBUTMEMHUNGRY),
00051     properties(KP_NONE), normalizer(NULL)
00052 {
00053 
00054 #ifdef USE_SVMLIGHT
00055     memset(&kernel_cache, 0x0, sizeof(KERNEL_CACHE));
00056 #endif //USE_SVMLIGHT
00057 
00058     set_normalizer(new CIdentityKernelNormalizer());
00059 }
00060 
00061 CKernel::CKernel(int32_t size)
00062 : CSGObject(), kernel_matrix(NULL), lhs(NULL), rhs(NULL), num_lhs(0),
00063     num_rhs(0), combined_kernel_weight(1), optimization_initialized(false),
00064     opt_type(FASTBUTMEMHUNGRY), properties(KP_NONE), normalizer(NULL)
00065 {
00066     if (size<10)
00067         size=10;
00068 
00069     cache_size=size;
00070 #ifdef USE_SVMLIGHT
00071     memset(&kernel_cache, 0x0, sizeof(KERNEL_CACHE));
00072 #endif //USE_SVMLIGHT
00073 
00074     if (get_is_initialized())
00075         SG_ERROR( "COptimizableKernel still initialized on destruction");
00076 
00077     set_normalizer(new CIdentityKernelNormalizer());
00078 }
00079 
00080 
00081 CKernel::CKernel(CFeatures* p_lhs, CFeatures* p_rhs, int32_t size) : CSGObject(),
00082     kernel_matrix(NULL), lhs(NULL), rhs(NULL), num_lhs(0), num_rhs(0),
00083     combined_kernel_weight(1), optimization_initialized(false),
00084     opt_type(FASTBUTMEMHUNGRY), properties(KP_NONE), normalizer(NULL)
00085 {
00086     if (size<10)
00087         size=10;
00088 
00089     cache_size=size;
00090 #ifdef USE_SVMLIGHT
00091     memset(&kernel_cache, 0x0, sizeof(KERNEL_CACHE));
00092 #endif //USE_SVMLIGHT
00093     if (get_is_initialized())
00094         SG_ERROR("Kernel initialized on construction.\n");
00095 
00096     set_normalizer(new CIdentityKernelNormalizer());
00097     init(p_lhs, p_rhs);
00098 }
00099 
00100 CKernel::~CKernel()
00101 {
00102     if (get_is_initialized())
00103         SG_ERROR("Kernel still initialized on destruction.\n");
00104 
00105     remove_lhs_and_rhs();
00106     SG_UNREF(normalizer);
00107 
00108     SG_INFO("Kernel deleted (%p).\n", this);
00109 }
00110 
00111 void CKernel::get_kernel_matrix(float64_t** dst, int32_t* m, int32_t* n)
00112 {
00113     ASSERT(dst && m && n);
00114 
00115     float64_t* result = NULL;
00116 
00117     if (has_features())
00118     {
00119         int32_t num_vec1=get_num_vec_lhs();
00120         int32_t num_vec2=get_num_vec_rhs();
00121         *m=num_vec1;
00122         *n=num_vec2;
00123 
00124         int64_t total_num = ((int64_t) num_vec1) * num_vec2;
00125         SG_DEBUG( "allocating memory for a kernel matrix"
00126                 " of size %dx%d\n", num_vec1, num_vec2);
00127 
00128         result=(float64_t*) malloc(sizeof(float64_t)*total_num);
00129         ASSERT(result);
00130         get_kernel_matrix<float64_t>(num_vec1,num_vec2, result);
00131     }
00132     else
00133         SG_ERROR( "no features assigned to kernel\n");
00134 
00135     *dst=result;
00136 }
00137 
00138 #ifdef USE_SVMLIGHT
00139 void CKernel::resize_kernel_cache(KERNELCACHE_IDX size, bool regression_hack)
00140 {
00141     if (size<10)
00142         size=10;
00143 
00144     kernel_cache_cleanup();
00145     cache_size=size;
00146 
00147     if (has_features() && get_num_vec_lhs())
00148         kernel_cache_init(cache_size, regression_hack);
00149 }
00150 #endif //USE_SVMLIGHT
00151 
00152 bool CKernel::init(CFeatures* l, CFeatures* r)
00153 {
00154     //make sure features were indeed supplied
00155     ASSERT(l);
00156     ASSERT(r);
00157 
00158     //make sure features are compatible
00159     ASSERT(l->get_feature_class()==r->get_feature_class());
00160     ASSERT(l->get_feature_type()==r->get_feature_type());
00161 
00162     //remove references to previous features
00163     remove_lhs_and_rhs();
00164 
00165     //increase reference counts
00166     SG_REF(l);
00167     if (l!=r)
00168         SG_REF(r);
00169 
00170     lhs=l;
00171     rhs=r;
00172 
00173     ASSERT(!num_lhs || num_lhs==l->get_num_vectors());
00174     ASSERT(!num_rhs || num_rhs==l->get_num_vectors());
00175 
00176     num_lhs=l->get_num_vectors();
00177     num_rhs=r->get_num_vectors();
00178 
00179     return true;
00180 }
00181 
00182 bool CKernel::set_normalizer(CKernelNormalizer* n)
00183 {
00184     SG_REF(n);
00185     if (lhs && rhs)
00186         n->init(this);
00187 
00188     SG_UNREF(normalizer);
00189     normalizer=n;
00190 
00191     return (normalizer!=NULL);
00192 }
00193 
00194 CKernelNormalizer* CKernel::get_normalizer()
00195 {
00196     SG_REF(normalizer)
00197     return normalizer;
00198 }
00199 
00200 bool CKernel::init_normalizer()
00201 {
00202     return normalizer->init(this);
00203 }
00204 
00205 void CKernel::cleanup()
00206 {
00207     remove_lhs_and_rhs();
00208 }
00209 
00210 #ifdef USE_SVMLIGHT
00211 /****************************** Cache handling *******************************/
00212 
00213 void CKernel::kernel_cache_init(int32_t buffsize, bool regression_hack)
00214 {
00215     int32_t totdoc=get_num_vec_lhs();
00216     if (totdoc<=0)
00217     {
00218         SG_ERROR("kernel has zero rows: num_lhs=%d num_rhs=%d\n",
00219                 get_num_vec_lhs(), get_num_vec_rhs());
00220     }
00221     uint64_t buffer_size=0;
00222     int32_t i;
00223 
00224     //in regression the additional constraints are made by doubling the training data
00225     if (regression_hack)
00226         totdoc*=2;
00227 
00228     buffer_size=((uint64_t) buffsize)*1024*1024/sizeof(KERNELCACHE_ELEM);
00229     if (buffer_size>((uint64_t) totdoc)*totdoc)
00230         buffer_size=((uint64_t) totdoc)*totdoc;
00231 
00232     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());
00233 
00234     //make sure it fits in the *signed* KERNELCACHE_IDX type
00235     ASSERT(buffer_size < (((uint64_t) 1) << (sizeof(KERNELCACHE_IDX)*8-1)));
00236 
00237     kernel_cache.index = new int32_t[totdoc];
00238     kernel_cache.occu = new int32_t[totdoc];
00239     kernel_cache.lru = new int32_t[totdoc];
00240     kernel_cache.invindex = new int32_t[totdoc];
00241     kernel_cache.active2totdoc = new int32_t[totdoc];
00242     kernel_cache.totdoc2active = new int32_t[totdoc];
00243     kernel_cache.buffer = new KERNELCACHE_ELEM[buffer_size];
00244     kernel_cache.buffsize=buffer_size;
00245     kernel_cache.max_elems=(int32_t) (kernel_cache.buffsize/totdoc);
00246 
00247     if(kernel_cache.max_elems>totdoc) {
00248         kernel_cache.max_elems=totdoc;
00249     }
00250 
00251     kernel_cache.elems=0;   // initialize cache
00252     for(i=0;i<totdoc;i++) {
00253         kernel_cache.index[i]=-1;
00254         kernel_cache.lru[i]=0;
00255     }
00256     for(i=0;i<totdoc;i++) {
00257         kernel_cache.occu[i]=0;
00258         kernel_cache.invindex[i]=-1;
00259     }
00260 
00261     kernel_cache.activenum=totdoc;;
00262     for(i=0;i<totdoc;i++) {
00263         kernel_cache.active2totdoc[i]=i;
00264         kernel_cache.totdoc2active[i]=i;
00265     }
00266 
00267     kernel_cache.time=0;
00268 }
00269 
00270 void CKernel::get_kernel_row(
00271     int32_t docnum, int32_t *active2dnum, float64_t *buffer, bool full_line)
00272 {
00273     int32_t i,j;
00274     KERNELCACHE_IDX start;
00275 
00276     int32_t num_vectors = get_num_vec_lhs();
00277     if (docnum>=num_vectors)
00278         docnum=2*num_vectors-1-docnum;
00279 
00280     /* is cached? */
00281     if(kernel_cache.index[docnum] != -1)
00282     {
00283         kernel_cache.lru[kernel_cache.index[docnum]]=kernel_cache.time; /* lru */
00284         start=((KERNELCACHE_IDX) kernel_cache.activenum)*kernel_cache.index[docnum];
00285 
00286         if (full_line)
00287         {
00288             for(j=0;j<get_num_vec_lhs();j++)
00289             {
00290                 if(kernel_cache.totdoc2active[j] >= 0)
00291                     buffer[j]=kernel_cache.buffer[start+kernel_cache.totdoc2active[j]];
00292                 else
00293                     buffer[j]=(float64_t) kernel(docnum, j);
00294             }
00295         }
00296         else
00297         {
00298             for(i=0;(j=active2dnum[i])>=0;i++)
00299             {
00300                 if(kernel_cache.totdoc2active[j] >= 0)
00301                     buffer[j]=kernel_cache.buffer[start+kernel_cache.totdoc2active[j]];
00302                 else
00303                 {
00304                     int32_t k=j;
00305                     if (k>=num_vectors)
00306                         k=2*num_vectors-1-k;
00307                     buffer[j]=(float64_t) kernel(docnum, k);
00308                 }
00309             }
00310         }
00311     }
00312     else
00313     {
00314         if (full_line)
00315         {
00316             for(j=0;j<get_num_vec_lhs();j++)
00317                 buffer[j]=(KERNELCACHE_ELEM) kernel(docnum, j);
00318         }
00319         else
00320         {
00321             for(i=0;(j=active2dnum[i])>=0;i++)
00322             {
00323                 int32_t k=j;
00324                 if (k>=num_vectors)
00325                     k=2*num_vectors-1-k;
00326                 buffer[j]=(KERNELCACHE_ELEM) kernel(docnum, k);
00327             }
00328         }
00329     }
00330 }
00331 
00332 
00333 // Fills cache for the row m
00334 void CKernel::cache_kernel_row(int32_t m)
00335 {
00336     register int32_t j,k,l;
00337     register KERNELCACHE_ELEM *cache;
00338 
00339     int32_t num_vectors = get_num_vec_lhs();
00340 
00341     if (m>=num_vectors)
00342         m=2*num_vectors-1-m;
00343 
00344     if(!kernel_cache_check(m))   // not cached yet
00345     {
00346         cache = kernel_cache_clean_and_malloc(m);
00347         if(cache) {
00348             l=kernel_cache.totdoc2active[m];
00349 
00350             for(j=0;j<kernel_cache.activenum;j++)  // fill cache
00351             {
00352                 k=kernel_cache.active2totdoc[j];
00353 
00354                 if((kernel_cache.index[k] != -1) && (l != -1) && (k != m)) {
00355                     cache[j]=kernel_cache.buffer[((KERNELCACHE_IDX) kernel_cache.activenum)
00356                         *kernel_cache.index[k]+l];
00357                 }
00358                 else
00359                 {
00360                     if (k>=num_vectors)
00361                         k=2*num_vectors-1-k;
00362 
00363                     cache[j]=kernel(m, k);
00364                 }
00365             }
00366         }
00367         else
00368             perror("Error: Kernel cache full! => increase cache size");
00369     }
00370 }
00371 
00372 
00373 void* CKernel::cache_multiple_kernel_row_helper(void* p)
00374 {
00375     int32_t j,k,l;
00376     S_KTHREAD_PARAM* params = (S_KTHREAD_PARAM*) p;
00377 
00378     for (int32_t i=params->start; i<params->end; i++)
00379     {
00380         KERNELCACHE_ELEM* cache=params->cache[i];
00381         int32_t m = params->uncached_rows[i];
00382         l=params->kernel_cache->totdoc2active[m];
00383 
00384         for(j=0;j<params->kernel_cache->activenum;j++)  // fill cache
00385         {
00386             k=params->kernel_cache->active2totdoc[j];
00387 
00388             if((params->kernel_cache->index[k] != -1) && (l != -1) && (!params->needs_computation[k])) {
00389                 cache[j]=params->kernel_cache->buffer[((KERNELCACHE_IDX) params->kernel_cache->activenum)
00390                     *params->kernel_cache->index[k]+l];
00391             }
00392             else
00393                 {
00394                     if (k>=params->num_vectors)
00395                         k=2*params->num_vectors-1-k;
00396 
00397                     cache[j]=params->kernel->kernel(m, k);
00398                 }
00399         }
00400 
00401         //now line m is cached
00402         params->needs_computation[m]=0;
00403     }
00404     return NULL;
00405 }
00406 
00407 // Fills cache for the rows in key
00408 void CKernel::cache_multiple_kernel_rows(int32_t* rows, int32_t num_rows)
00409 {
00410 #ifndef WIN32
00411     if (parallel->get_num_threads()<2)
00412     {
00413 #endif
00414         for(int32_t i=0;i<num_rows;i++)
00415             cache_kernel_row(rows[i]);
00416 #ifndef WIN32
00417     }
00418     else
00419     {
00420         // fill up kernel cache
00421         int32_t* uncached_rows = new int32_t[num_rows];
00422         KERNELCACHE_ELEM** cache = new KERNELCACHE_ELEM*[num_rows];
00423         pthread_t* threads = new pthread_t[parallel->get_num_threads()-1];
00424         S_KTHREAD_PARAM* params = new S_KTHREAD_PARAM[parallel->get_num_threads()-1];
00425         int32_t num_threads=parallel->get_num_threads()-1;
00426         int32_t num_vec=get_num_vec_lhs();
00427         ASSERT(num_vec>0);
00428         uint8_t* needs_computation=new uint8_t[num_vec];
00429         memset(needs_computation, 0, sizeof(uint8_t)*num_vec);
00430         int32_t step=0;
00431         int32_t num=0;
00432         int32_t end=0;
00433 
00434         // allocate cachelines if necessary
00435         for (int32_t i=0; i<num_rows; i++)
00436         {
00437             int32_t idx=rows[i];
00438             if (kernel_cache_check(idx))
00439                 continue;
00440 
00441             if (idx>=num_vec)
00442                 idx=2*num_vec-1-idx;
00443 
00444             needs_computation[idx]=1;
00445             uncached_rows[num]=idx;
00446             cache[num]= kernel_cache_clean_and_malloc(idx);
00447 
00448             if (!cache[num])
00449                 SG_ERROR("Kernel cache full! => increase cache size\n");
00450 
00451             num++;
00452         }
00453 
00454         if (num>0)
00455         {
00456             step= num/parallel->get_num_threads();
00457 
00458             if (step<1)
00459             {
00460                 num_threads=num-1;
00461                 step=1;
00462             }
00463 
00464             for (int32_t t=0; t<num_threads; t++)
00465             {
00466                 params[t].kernel = this;
00467                 params[t].kernel_cache = &kernel_cache;
00468                 params[t].cache = cache;
00469                 params[t].uncached_rows = uncached_rows;
00470                 params[t].needs_computation = needs_computation;
00471                 params[t].num_uncached = num;
00472                 params[t].start = t*step;
00473                 params[t].end = (t+1)*step;
00474                 params[t].num_vectors = get_num_vec_lhs();
00475                 end=params[t].end;
00476 
00477                 if (pthread_create(&threads[t], NULL, CKernel::cache_multiple_kernel_row_helper, (void*)&params[t]) != 0)
00478                 {
00479                     num_threads=t;
00480                     end=t*step;
00481                     SG_WARNING("thread creation failed\n");
00482                     break;
00483                 }
00484             }
00485         }
00486         else
00487             num_threads=-1;
00488 
00489 
00490         S_KTHREAD_PARAM last_param;
00491         last_param.kernel = this;
00492         last_param.kernel_cache = &kernel_cache;
00493         last_param.cache = cache;
00494         last_param.uncached_rows = uncached_rows;
00495         last_param.needs_computation = needs_computation;
00496         last_param.start = end;
00497         last_param.num_uncached = num;
00498         last_param.end = num;
00499         last_param.num_vectors = get_num_vec_lhs();
00500 
00501         cache_multiple_kernel_row_helper(&last_param);
00502 
00503 
00504         for (int32_t t=0; t<num_threads; t++)
00505         {
00506             if (pthread_join(threads[t], NULL) != 0)
00507                 SG_WARNING( "pthread_join failed\n");
00508         }
00509 
00510         delete[] needs_computation;
00511         delete[] params;
00512         delete[] threads;
00513         delete[] cache;
00514         delete[] uncached_rows;
00515     }
00516 #endif
00517 }
00518 
00519 // remove numshrink columns in the cache
00520 // which correspond to examples marked
00521 void CKernel::kernel_cache_shrink(
00522     int32_t totdoc, int32_t numshrink, int32_t *after)
00523 {
00524     register int32_t i,j,jj,scount;     // 0 in after.
00525     KERNELCACHE_IDX from=0,to=0;
00526     int32_t *keep;
00527 
00528     keep=new int32_t[totdoc];
00529     for(j=0;j<totdoc;j++) {
00530         keep[j]=1;
00531     }
00532     scount=0;
00533     for(jj=0;(jj<kernel_cache.activenum) && (scount<numshrink);jj++) {
00534         j=kernel_cache.active2totdoc[jj];
00535         if(!after[j]) {
00536             scount++;
00537             keep[j]=0;
00538         }
00539     }
00540 
00541     for(i=0;i<kernel_cache.max_elems;i++) {
00542         for(jj=0;jj<kernel_cache.activenum;jj++) {
00543             j=kernel_cache.active2totdoc[jj];
00544             if(!keep[j]) {
00545                 from++;
00546             }
00547             else {
00548                 kernel_cache.buffer[to]=kernel_cache.buffer[from];
00549                 to++;
00550                 from++;
00551             }
00552         }
00553     }
00554 
00555     kernel_cache.activenum=0;
00556     for(j=0;j<totdoc;j++) {
00557         if((keep[j]) && (kernel_cache.totdoc2active[j] != -1)) {
00558             kernel_cache.active2totdoc[kernel_cache.activenum]=j;
00559             kernel_cache.totdoc2active[j]=kernel_cache.activenum;
00560             kernel_cache.activenum++;
00561         }
00562         else {
00563             kernel_cache.totdoc2active[j]=-1;
00564         }
00565     }
00566 
00567     kernel_cache.max_elems=
00568         (int32_t)(kernel_cache.buffsize/kernel_cache.activenum);
00569     if(kernel_cache.max_elems>totdoc) {
00570         kernel_cache.max_elems=totdoc;
00571     }
00572 
00573     delete[] keep;
00574 
00575 }
00576 
00577 void CKernel::kernel_cache_reset_lru()
00578 {
00579     int32_t maxlru=0,k;
00580 
00581     for(k=0;k<kernel_cache.max_elems;k++) {
00582         if(maxlru < kernel_cache.lru[k])
00583             maxlru=kernel_cache.lru[k];
00584     }
00585     for(k=0;k<kernel_cache.max_elems;k++) {
00586         kernel_cache.lru[k]-=maxlru;
00587     }
00588 }
00589 
00590 void CKernel::kernel_cache_cleanup()
00591 {
00592     delete[] kernel_cache.index;
00593     delete[] kernel_cache.occu;
00594     delete[] kernel_cache.lru;
00595     delete[] kernel_cache.invindex;
00596     delete[] kernel_cache.active2totdoc;
00597     delete[] kernel_cache.totdoc2active;
00598     delete[] kernel_cache.buffer;
00599     memset(&kernel_cache, 0x0, sizeof(KERNEL_CACHE));
00600 }
00601 
00602 int32_t CKernel::kernel_cache_malloc()
00603 {
00604   int32_t i;
00605 
00606   if(kernel_cache_space_available()) {
00607     for(i=0;i<kernel_cache.max_elems;i++) {
00608       if(!kernel_cache.occu[i]) {
00609     kernel_cache.occu[i]=1;
00610     kernel_cache.elems++;
00611     return(i);
00612       }
00613     }
00614   }
00615   return(-1);
00616 }
00617 
00618 void CKernel::kernel_cache_free(int32_t cacheidx)
00619 {
00620     kernel_cache.occu[cacheidx]=0;
00621     kernel_cache.elems--;
00622 }
00623 
00624 // remove least recently used cache
00625 // element
00626 int32_t CKernel::kernel_cache_free_lru()
00627 {
00628   register int32_t k,least_elem=-1,least_time;
00629 
00630   least_time=kernel_cache.time+1;
00631   for(k=0;k<kernel_cache.max_elems;k++) {
00632     if(kernel_cache.invindex[k] != -1) {
00633       if(kernel_cache.lru[k]<least_time) {
00634     least_time=kernel_cache.lru[k];
00635     least_elem=k;
00636       }
00637     }
00638   }
00639 
00640   if(least_elem != -1) {
00641     kernel_cache_free(least_elem);
00642     kernel_cache.index[kernel_cache.invindex[least_elem]]=-1;
00643     kernel_cache.invindex[least_elem]=-1;
00644     return(1);
00645   }
00646   return(0);
00647 }
00648 
00649 // Get a free cache entry. In case cache is full, the lru
00650 // element is removed.
00651 KERNELCACHE_ELEM* CKernel::kernel_cache_clean_and_malloc(int32_t cacheidx)
00652 {
00653     int32_t result;
00654     if((result = kernel_cache_malloc()) == -1) {
00655         if(kernel_cache_free_lru()) {
00656             result = kernel_cache_malloc();
00657         }
00658     }
00659     kernel_cache.index[cacheidx]=result;
00660     if(result == -1) {
00661         return(0);
00662     }
00663     kernel_cache.invindex[result]=cacheidx;
00664     kernel_cache.lru[kernel_cache.index[cacheidx]]=kernel_cache.time; // lru
00665     return &kernel_cache.buffer[((KERNELCACHE_IDX) kernel_cache.activenum)*kernel_cache.index[cacheidx]];
00666 }
00667 #endif //USE_SVMLIGHT
00668 
00669 void CKernel::load(CFile* loader)
00670 {
00671 }
00672 
00673 void CKernel::save(CFile* writer)
00674 {
00675     int32_t m,n;
00676     float64_t* km=get_kernel_matrix<float64_t>(m,n, NULL);
00677     writer->set_real_matrix(km, m,n);
00678     delete[] km;
00679 }
00680 
00681 void CKernel::remove_lhs_and_rhs()
00682 {
00683     if (rhs!=lhs)
00684         SG_UNREF(rhs);
00685     rhs = NULL;
00686     num_rhs=0;
00687 
00688     SG_UNREF(lhs);
00689     lhs = NULL;
00690     num_lhs=0;
00691 
00692 #ifdef USE_SVMLIGHT
00693     cache_reset();
00694 #endif //USE_SVMLIGHT
00695 }
00696 
00697 void CKernel::remove_lhs()
00698 {
00699     if (rhs==lhs)
00700         rhs=NULL;
00701     SG_UNREF(lhs);
00702     lhs = NULL;
00703     num_lhs=NULL;
00704 
00705 #ifdef USE_SVMLIGHT
00706     cache_reset();
00707 #endif //USE_SVMLIGHT
00708 }
00709 
00711 void CKernel::remove_rhs()
00712 {
00713     if (rhs!=lhs)
00714         SG_UNREF(rhs);
00715     rhs = NULL;
00716     num_rhs=NULL;
00717 
00718 #ifdef USE_SVMLIGHT
00719     cache_reset();
00720 #endif //USE_SVMLIGHT
00721 }
00722 
00723 
00724 void CKernel::list_kernel()
00725 {
00726     SG_INFO( "%p - \"%s\" weight=%1.2f OPT:%s", this, get_name(),
00727             get_combined_kernel_weight(),
00728             get_optimization_type()==FASTBUTMEMHUNGRY ? "FASTBUTMEMHUNGRY" :
00729             "SLOWBUTMEMEFFICIENT");
00730 
00731     switch (get_kernel_type())
00732     {
00733         case K_UNKNOWN:
00734             SG_INFO( "K_UNKNOWN ");
00735             break;
00736         case K_LINEAR:
00737             SG_INFO( "K_LINEAR ");
00738             break;
00739         case K_SPARSELINEAR:
00740             SG_INFO( "K_SPARSELINEAR ");
00741             break;
00742         case K_POLY:
00743             SG_INFO( "K_POLY ");
00744             break;
00745         case K_GAUSSIAN:
00746             SG_INFO( "K_GAUSSIAN ");
00747             break;
00748         case K_SPARSEGAUSSIAN:
00749             SG_INFO( "K_SPARSEGAUSSIAN ");
00750             break;
00751         case K_GAUSSIANSHIFT:
00752             SG_INFO( "K_GAUSSIANSHIFT ");
00753             break;
00754         case K_HISTOGRAM:
00755             SG_INFO( "K_HISTOGRAM ");
00756             break;
00757         case K_SALZBERG:
00758             SG_INFO( "K_SALZBERG ");
00759             break;
00760         case K_LOCALITYIMPROVED:
00761             SG_INFO( "K_LOCALITYIMPROVED ");
00762             break;
00763         case K_SIMPLELOCALITYIMPROVED:
00764             SG_INFO( "K_SIMPLELOCALITYIMPROVED ");
00765             break;
00766         case K_FIXEDDEGREE:
00767             SG_INFO( "K_FIXEDDEGREE ");
00768             break;
00769         case K_WEIGHTEDDEGREE:
00770             SG_INFO( "K_WEIGHTEDDEGREE ");
00771             break;
00772         case K_WEIGHTEDDEGREEPOS:
00773             SG_INFO( "K_WEIGHTEDDEGREEPOS ");
00774             break;
00775         case K_WEIGHTEDDEGREERBF:
00776             SG_INFO( "K_WEIGHTEDDEGREERBF ");
00777             break;
00778         case K_WEIGHTEDCOMMWORDSTRING:
00779             SG_INFO( "K_WEIGHTEDCOMMWORDSTRING ");
00780             break;
00781         case K_POLYMATCH:
00782             SG_INFO( "K_POLYMATCH ");
00783             break;
00784         case K_ALIGNMENT:
00785             SG_INFO( "K_ALIGNMENT ");
00786             break;
00787         case K_COMMWORDSTRING:
00788             SG_INFO( "K_COMMWORDSTRING ");
00789             break;
00790         case K_COMMULONGSTRING:
00791             SG_INFO( "K_COMMULONGSTRING ");
00792             break;
00793         case K_SPECTRUMMISMATCHRBF:
00794             SG_INFO( "K_SPECTRUMMISMATCHRBF ");
00795             break;
00796         case K_COMBINED:
00797             SG_INFO( "K_COMBINED ");
00798             break;
00799         case K_AUC:
00800             SG_INFO( "K_AUC ");
00801             break;
00802         case K_CUSTOM:
00803             SG_INFO( "K_CUSTOM ");
00804             break;
00805         case K_SIGMOID:
00806             SG_INFO( "K_SIGMOID ");
00807             break;
00808         case K_CHI2:
00809             SG_INFO( "K_CHI2 ");
00810             break;
00811         case K_DIAG:
00812             SG_INFO( "K_DIAG ");
00813             break;
00814         case K_CONST:
00815             SG_INFO( "K_CONST ");
00816             break;
00817         case K_DISTANCE:
00818             SG_INFO( "K_DISTANCE ");
00819             break;
00820         case K_LOCALALIGNMENT:
00821             SG_INFO( "K_LOCALALIGNMENT ");
00822             break;
00823         case K_TPPK:
00824             SG_INFO( "K_TPPK ");
00825             break;
00826         default:
00827          SG_ERROR( "ERROR UNKNOWN KERNEL TYPE");
00828             break;
00829     }
00830 
00831     switch (get_feature_class())
00832     {
00833         case C_UNKNOWN:
00834             SG_INFO( "C_UNKNOWN ");
00835             break;
00836         case C_SIMPLE:
00837             SG_INFO( "C_SIMPLE ");
00838             break;
00839         case C_SPARSE:
00840             SG_INFO( "C_SPARSE ");
00841             break;
00842         case C_STRING:
00843             SG_INFO( "C_STRING ");
00844             break;
00845         case C_COMBINED:
00846             SG_INFO( "C_COMBINED ");
00847             break;
00848         case C_ANY:
00849             SG_INFO( "C_ANY ");
00850             break;
00851         default:
00852          SG_ERROR( "ERROR UNKNOWN FEATURE CLASS");
00853     }
00854 
00855     switch (get_feature_type())
00856     {
00857         case F_UNKNOWN:
00858             SG_INFO( "F_UNKNOWN ");
00859             break;
00860         case F_DREAL:
00861             SG_INFO( "F_REAL ");
00862             break;
00863         case F_SHORT:
00864             SG_INFO( "F_SHORT ");
00865             break;
00866         case F_CHAR:
00867             SG_INFO( "F_CHAR ");
00868             break;
00869         case F_INT:
00870             SG_INFO( "F_INT ");
00871             break;
00872         case F_BYTE:
00873             SG_INFO( "F_BYTE ");
00874             break;
00875         case F_WORD:
00876             SG_INFO( "F_WORD ");
00877             break;
00878         case F_ULONG:
00879             SG_INFO( "F_ULONG ");
00880             break;
00881         case F_ANY:
00882             SG_INFO( "F_ANY ");
00883             break;
00884         default:
00885          SG_ERROR( "ERROR UNKNOWN FEATURE TYPE");
00886             break;
00887     }
00888     SG_INFO( "\n");
00889 }
00890 
00891 bool CKernel::init_optimization(
00892     int32_t count, int32_t *IDX, float64_t * weights)
00893 {
00894    SG_ERROR( "kernel does not support linadd optimization\n");
00895     return false ;
00896 }
00897 
00898 bool CKernel::delete_optimization()
00899 {
00900    SG_ERROR( "kernel does not support linadd optimization\n");
00901     return false;
00902 }
00903 
00904 float64_t CKernel::compute_optimized(int32_t vector_idx)
00905 {
00906    SG_ERROR( "kernel does not support linadd optimization\n");
00907     return 0;
00908 }
00909 
00910 void CKernel::compute_batch(
00911     int32_t num_vec, int32_t* vec_idx, float64_t* target, int32_t num_suppvec,
00912     int32_t* IDX, float64_t* weights, float64_t factor)
00913 {
00914    SG_ERROR( "kernel does not support batch computation\n");
00915 }
00916 
00917 void CKernel::add_to_normal(int32_t vector_idx, float64_t weight)
00918 {
00919    SG_ERROR( "kernel does not support linadd optimization, add_to_normal not implemented\n");
00920 }
00921 
00922 void CKernel::clear_normal()
00923 {
00924    SG_ERROR( "kernel does not support linadd optimization, clear_normal not implemented\n");
00925 }
00926 
00927 int32_t CKernel::get_num_subkernels()
00928 {
00929     return 1;
00930 }
00931 
00932 void CKernel::compute_by_subkernel(
00933     int32_t vector_idx, float64_t * subkernel_contrib)
00934 {
00935    SG_ERROR( "kernel compute_by_subkernel not implemented\n");
00936 }
00937 
00938 const float64_t* CKernel::get_subkernel_weights(int32_t &num_weights)
00939 {
00940     num_weights=1 ;
00941     return &combined_kernel_weight ;
00942 }
00943 
00944 void CKernel::set_subkernel_weights(float64_t* weights, int32_t num_weights)
00945 {
00946     combined_kernel_weight = weights[0] ;
00947     if (num_weights!=1)
00948       SG_ERROR( "number of subkernel weights should be one ...\n");
00949 }
00950 
00951 bool CKernel::init_optimization_svm(CSVM * svm)
00952 {
00953     int32_t num_suppvec=svm->get_num_support_vectors();
00954     int32_t* sv_idx=new int32_t[num_suppvec];
00955     float64_t* sv_weight=new float64_t[num_suppvec];
00956 
00957     for (int32_t i=0; i<num_suppvec; i++)
00958     {
00959         sv_idx[i]    = svm->get_support_vector(i);
00960         sv_weight[i] = svm->get_alpha(i);
00961     }
00962     bool ret = init_optimization(num_suppvec, sv_idx, sv_weight);
00963 
00964     delete[] sv_idx;
00965     delete[] sv_weight;
00966     return ret;
00967 }
00968 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation