|
SHOGUN v0.9.3
|
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*)¶ms[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