SHOGUN
v1.1.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 1999-2009 Soeren Sonnenburg 00008 * Written (W) 1999-2008 Gunnar Raetsch 00009 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00010 */ 00011 00012 #include <shogun/lib/common.h> 00013 #include <shogun/io/SGIO.h> 00014 #include <shogun/lib/Signal.h> 00015 #include <shogun/base/Parallel.h> 00016 00017 #include <shogun/kernel/Kernel.h> 00018 #include <shogun/kernel/CombinedKernel.h> 00019 #include <shogun/kernel/CustomKernel.h> 00020 #include <shogun/features/CombinedFeatures.h> 00021 00022 #include <string.h> 00023 00024 #ifndef WIN32 00025 #include <pthread.h> 00026 #endif 00027 00028 using namespace shogun; 00029 00030 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00031 struct S_THREAD_PARAM 00032 { 00033 CKernel* kernel; 00034 float64_t* result; 00035 int32_t* vec_idx; 00036 int32_t start; 00037 int32_t end; 00039 float64_t* weights; 00040 int32_t* IDX; 00041 int32_t num_suppvec; 00042 }; 00043 #endif // DOXYGEN_SHOULD_SKIP_THIS 00044 00045 CCombinedKernel::CCombinedKernel(int32_t size, bool asw) 00046 : CKernel(size), append_subkernel_weights(asw) 00047 { 00048 init(); 00049 00050 if (append_subkernel_weights) 00051 SG_INFO( "(subkernel weights are appended)\n") ; 00052 00053 SG_INFO("Combined kernel created (%p)\n", this) ; 00054 } 00055 00056 CCombinedKernel::~CCombinedKernel() 00057 { 00058 SG_FREE(subkernel_weights_buffer); 00059 subkernel_weights_buffer=NULL; 00060 00061 cleanup(); 00062 SG_UNREF(kernel_list); 00063 00064 SG_INFO("Combined kernel deleted (%p).\n", this); 00065 } 00066 00067 bool CCombinedKernel::init(CFeatures* l, CFeatures* r) 00068 { 00069 CKernel::init(l,r); 00070 ASSERT(l->get_feature_class()==C_COMBINED); 00071 ASSERT(r->get_feature_class()==C_COMBINED); 00072 ASSERT(l->get_feature_type()==F_UNKNOWN); 00073 ASSERT(r->get_feature_type()==F_UNKNOWN); 00074 00075 CFeatures* lf=NULL; 00076 CFeatures* rf=NULL; 00077 CKernel* k=NULL; 00078 00079 bool result=true; 00080 00081 CListElement* lfc = NULL; 00082 CListElement* rfc = NULL; 00083 lf=((CCombinedFeatures*) l)->get_first_feature_obj(lfc); 00084 rf=((CCombinedFeatures*) r)->get_first_feature_obj(rfc); 00085 CListElement* current = NULL; 00086 k=get_first_kernel(current); 00087 00088 while ( result && k ) 00089 { 00090 // skip over features - the custom kernel does not need any 00091 if (k->get_kernel_type() != K_CUSTOM) 00092 { 00093 if (!lf || !rf) 00094 { 00095 SG_UNREF(lf); 00096 SG_UNREF(rf); 00097 SG_UNREF(k); 00098 SG_ERROR( "CombinedKernel: Number of features/kernels does not match - bailing out\n"); 00099 } 00100 00101 SG_DEBUG( "Initializing 0x%p - \"%s\"\n", this, k->get_name()); 00102 result=k->init(lf,rf); 00103 SG_UNREF(lf); 00104 SG_UNREF(rf); 00105 00106 lf=((CCombinedFeatures*) l)->get_next_feature_obj(lfc) ; 00107 rf=((CCombinedFeatures*) r)->get_next_feature_obj(rfc) ; 00108 } 00109 else 00110 { 00111 SG_DEBUG( "Initializing 0x%p - \"%s\" (skipping init, this is a CUSTOM kernel)\n", this, k->get_name()); 00112 if (!k->has_features()) 00113 SG_ERROR("No kernel matrix was assigned to this Custom kernel\n"); 00114 if (k->get_num_vec_lhs() != num_lhs) 00115 SG_ERROR("Number of lhs-feature vectors (%d) not match with number of rows (%d) of custom kernel\n", num_lhs, k->get_num_vec_lhs()); 00116 if (k->get_num_vec_rhs() != num_rhs) 00117 SG_ERROR("Number of rhs-feature vectors (%d) not match with number of cols (%d) of custom kernel\n", num_rhs, k->get_num_vec_rhs()); 00118 } 00119 00120 SG_UNREF(k); 00121 k=get_next_kernel(current) ; 00122 } 00123 00124 if (!result) 00125 { 00126 SG_INFO( "CombinedKernel: Initialising the following kernel failed\n"); 00127 if (k) 00128 k->list_kernel(); 00129 else 00130 SG_INFO( "<NULL>\n"); 00131 return false; 00132 } 00133 00134 if ((lf!=NULL) || (rf!=NULL) || (k!=NULL)) 00135 { 00136 SG_UNREF(lf); 00137 SG_UNREF(rf); 00138 SG_UNREF(k); 00139 SG_ERROR( "CombinedKernel: Number of features/kernels does not match - bailing out\n"); 00140 } 00141 00142 init_normalizer(); 00143 initialized=true; 00144 return true; 00145 } 00146 00147 void CCombinedKernel::remove_lhs() 00148 { 00149 delete_optimization(); 00150 00151 CListElement* current = NULL ; 00152 CKernel* k=get_first_kernel(current); 00153 00154 while (k) 00155 { 00156 if (k->get_kernel_type() != K_CUSTOM) 00157 k->remove_lhs(); 00158 00159 SG_UNREF(k); 00160 k=get_next_kernel(current); 00161 } 00162 CKernel::remove_lhs(); 00163 00164 num_lhs=0; 00165 } 00166 00167 void CCombinedKernel::remove_rhs() 00168 { 00169 CListElement* current = NULL ; 00170 CKernel* k=get_first_kernel(current); 00171 00172 while (k) 00173 { 00174 if (k->get_kernel_type() != K_CUSTOM) 00175 k->remove_rhs(); 00176 SG_UNREF(k); 00177 k=get_next_kernel(current); 00178 } 00179 CKernel::remove_rhs(); 00180 00181 num_rhs=0; 00182 } 00183 00184 void CCombinedKernel::remove_lhs_and_rhs() 00185 { 00186 delete_optimization(); 00187 00188 CListElement* current = NULL ; 00189 CKernel* k=get_first_kernel(current); 00190 00191 while (k) 00192 { 00193 if (k->get_kernel_type() != K_CUSTOM) 00194 k->remove_lhs_and_rhs(); 00195 SG_UNREF(k); 00196 k=get_next_kernel(current); 00197 } 00198 00199 CKernel::remove_lhs_and_rhs(); 00200 00201 num_lhs=0; 00202 num_rhs=0; 00203 } 00204 00205 void CCombinedKernel::cleanup() 00206 { 00207 CListElement* current = NULL ; 00208 CKernel* k=get_first_kernel(current); 00209 00210 while (k) 00211 { 00212 k->cleanup(); 00213 SG_UNREF(k); 00214 k=get_next_kernel(current); 00215 } 00216 00217 delete_optimization(); 00218 00219 CKernel::cleanup(); 00220 00221 num_lhs=0; 00222 num_rhs=0; 00223 } 00224 00225 void CCombinedKernel::list_kernels() 00226 { 00227 CKernel* k; 00228 00229 SG_INFO( "BEGIN COMBINED KERNEL LIST - "); 00230 this->list_kernel(); 00231 00232 CListElement* current = NULL ; 00233 k=get_first_kernel(current); 00234 while (k) 00235 { 00236 k->list_kernel(); 00237 SG_UNREF(k); 00238 k=get_next_kernel(current); 00239 } 00240 SG_INFO( "END COMBINED KERNEL LIST - "); 00241 } 00242 00243 float64_t CCombinedKernel::compute(int32_t x, int32_t y) 00244 { 00245 float64_t result=0; 00246 CListElement* current = NULL ; 00247 CKernel* k=get_first_kernel(current); 00248 while (k) 00249 { 00250 if (k->get_combined_kernel_weight()!=0) 00251 result += k->get_combined_kernel_weight() * k->kernel(x,y); 00252 SG_UNREF(k); 00253 k=get_next_kernel(current); 00254 } 00255 00256 return result; 00257 } 00258 00259 bool CCombinedKernel::init_optimization( 00260 int32_t count, int32_t *IDX, float64_t *weights) 00261 { 00262 SG_DEBUG( "initializing CCombinedKernel optimization\n"); 00263 00264 delete_optimization(); 00265 00266 CListElement* current=NULL; 00267 CKernel *k=get_first_kernel(current); 00268 bool have_non_optimizable=false; 00269 00270 while(k) 00271 { 00272 bool ret=true; 00273 00274 if (k && k->has_property(KP_LINADD)) 00275 ret=k->init_optimization(count, IDX, weights); 00276 else 00277 { 00278 SG_WARNING("non-optimizable kernel 0x%X in kernel-list\n", k); 00279 have_non_optimizable=true; 00280 } 00281 00282 if (!ret) 00283 { 00284 have_non_optimizable=true; 00285 SG_WARNING("init_optimization of kernel 0x%X failed\n", k); 00286 } 00287 00288 SG_UNREF(k); 00289 k=get_next_kernel(current); 00290 } 00291 00292 if (have_non_optimizable) 00293 { 00294 SG_WARNING( "some kernels in the kernel-list are not optimized\n"); 00295 00296 sv_idx=SG_MALLOC(int32_t, count); 00297 sv_weight=SG_MALLOC(float64_t, count); 00298 sv_count=count; 00299 for (int32_t i=0; i<count; i++) 00300 { 00301 sv_idx[i]=IDX[i]; 00302 sv_weight[i]=weights[i]; 00303 } 00304 } 00305 set_is_initialized(true); 00306 00307 return true; 00308 } 00309 00310 bool CCombinedKernel::delete_optimization() 00311 { 00312 CListElement* current = NULL ; 00313 CKernel* k = get_first_kernel(current); 00314 00315 while(k) 00316 { 00317 if (k->has_property(KP_LINADD)) 00318 k->delete_optimization(); 00319 00320 SG_UNREF(k); 00321 k = get_next_kernel(current); 00322 } 00323 00324 SG_FREE(sv_idx); 00325 sv_idx = NULL; 00326 00327 SG_FREE(sv_weight); 00328 sv_weight = NULL; 00329 00330 sv_count = 0; 00331 set_is_initialized(false); 00332 00333 return true; 00334 } 00335 00336 void CCombinedKernel::compute_batch( 00337 int32_t num_vec, int32_t* vec_idx, float64_t* result, int32_t num_suppvec, 00338 int32_t* IDX, float64_t* weights, float64_t factor) 00339 { 00340 ASSERT(num_vec<=get_num_vec_rhs()) 00341 ASSERT(num_vec>0); 00342 ASSERT(vec_idx); 00343 ASSERT(result); 00344 00345 //we have to do the optimization business ourselves but lets 00346 //make sure we start cleanly 00347 delete_optimization(); 00348 00349 CListElement* current = NULL ; 00350 CKernel * k = get_first_kernel(current) ; 00351 00352 while(k) 00353 { 00354 if (k && k->has_property(KP_BATCHEVALUATION)) 00355 { 00356 if (k->get_combined_kernel_weight()!=0) 00357 k->compute_batch(num_vec, vec_idx, result, num_suppvec, IDX, weights, k->get_combined_kernel_weight()); 00358 } 00359 else 00360 emulate_compute_batch(k, num_vec, vec_idx, result, num_suppvec, IDX, weights); 00361 00362 SG_UNREF(k); 00363 k = get_next_kernel(current); 00364 } 00365 00366 //clean up 00367 delete_optimization(); 00368 } 00369 00370 void* CCombinedKernel::compute_optimized_kernel_helper(void* p) 00371 { 00372 S_THREAD_PARAM* params= (S_THREAD_PARAM*) p; 00373 int32_t* vec_idx=params->vec_idx; 00374 CKernel* k=params->kernel; 00375 float64_t* result=params->result; 00376 00377 for (int32_t i=params->start; i<params->end; i++) 00378 result[i] += k->get_combined_kernel_weight()*k->compute_optimized(vec_idx[i]); 00379 00380 return NULL; 00381 } 00382 00383 void* CCombinedKernel::compute_kernel_helper(void* p) 00384 { 00385 S_THREAD_PARAM* params= (S_THREAD_PARAM*) p; 00386 int32_t* vec_idx=params->vec_idx; 00387 CKernel* k=params->kernel; 00388 float64_t* result=params->result; 00389 float64_t* weights=params->weights; 00390 int32_t* IDX=params->IDX; 00391 int32_t num_suppvec=params->num_suppvec; 00392 00393 for (int32_t i=params->start; i<params->end; i++) 00394 { 00395 float64_t sub_result=0; 00396 for (int32_t j=0; j<num_suppvec; j++) 00397 sub_result += weights[j] * k->kernel(IDX[j], vec_idx[i]); 00398 00399 result[i] += k->get_combined_kernel_weight()*sub_result; 00400 } 00401 00402 return NULL; 00403 } 00404 00405 void CCombinedKernel::emulate_compute_batch( 00406 CKernel* k, int32_t num_vec, int32_t* vec_idx, float64_t* result, 00407 int32_t num_suppvec, int32_t* IDX, float64_t* weights) 00408 { 00409 ASSERT(k); 00410 ASSERT(result); 00411 00412 if (k->has_property(KP_LINADD)) 00413 { 00414 if (k->get_combined_kernel_weight()!=0) 00415 { 00416 k->init_optimization(num_suppvec, IDX, weights); 00417 00418 int32_t num_threads=parallel->get_num_threads(); 00419 ASSERT(num_threads>0); 00420 00421 if (num_threads < 2) 00422 { 00423 S_THREAD_PARAM params; 00424 params.kernel=k; 00425 params.result=result; 00426 params.start=0; 00427 params.end=num_vec; 00428 params.vec_idx = vec_idx; 00429 compute_optimized_kernel_helper((void*) ¶ms); 00430 } 00431 #ifndef WIN32 00432 else 00433 { 00434 pthread_t* threads = SG_MALLOC(pthread_t, num_threads-1); 00435 S_THREAD_PARAM* params = SG_MALLOC(S_THREAD_PARAM, num_threads); 00436 int32_t step= num_vec/num_threads; 00437 00438 int32_t t; 00439 00440 for (t=0; t<num_threads-1; t++) 00441 { 00442 params[t].kernel = k; 00443 params[t].result = result; 00444 params[t].start = t*step; 00445 params[t].end = (t+1)*step; 00446 params[t].vec_idx = vec_idx; 00447 pthread_create(&threads[t], NULL, CCombinedKernel::compute_optimized_kernel_helper, (void*)¶ms[t]); 00448 } 00449 00450 params[t].kernel = k; 00451 params[t].result = result; 00452 params[t].start = t*step; 00453 params[t].end = num_vec; 00454 params[t].vec_idx = vec_idx; 00455 compute_optimized_kernel_helper((void*) ¶ms[t]); 00456 00457 for (t=0; t<num_threads-1; t++) 00458 pthread_join(threads[t], NULL); 00459 00460 SG_FREE(params); 00461 SG_FREE(threads); 00462 } 00463 #endif 00464 00465 k->delete_optimization(); 00466 } 00467 } 00468 else 00469 { 00470 ASSERT(IDX!=NULL || num_suppvec==0); 00471 ASSERT(weights!=NULL || num_suppvec==0); 00472 00473 if (k->get_combined_kernel_weight()!=0) 00474 { // compute the usual way for any non-optimized kernel 00475 int32_t num_threads=parallel->get_num_threads(); 00476 ASSERT(num_threads>0); 00477 00478 if (num_threads < 2) 00479 { 00480 S_THREAD_PARAM params; 00481 params.kernel=k; 00482 params.result=result; 00483 params.start=0; 00484 params.end=num_vec; 00485 params.vec_idx = vec_idx; 00486 params.IDX = IDX; 00487 params.weights = weights; 00488 params.num_suppvec = num_suppvec; 00489 compute_kernel_helper((void*) ¶ms); 00490 } 00491 #ifndef WIN32 00492 else 00493 { 00494 pthread_t* threads = SG_MALLOC(pthread_t, num_threads-1); 00495 S_THREAD_PARAM* params = SG_MALLOC(S_THREAD_PARAM, num_threads); 00496 int32_t step= num_vec/num_threads; 00497 00498 int32_t t; 00499 00500 for (t=0; t<num_threads-1; t++) 00501 { 00502 params[t].kernel = k; 00503 params[t].result = result; 00504 params[t].start = t*step; 00505 params[t].end = (t+1)*step; 00506 params[t].vec_idx = vec_idx; 00507 params[t].IDX = IDX; 00508 params[t].weights = weights; 00509 params[t].num_suppvec = num_suppvec; 00510 pthread_create(&threads[t], NULL, CCombinedKernel::compute_kernel_helper, (void*)¶ms[t]); 00511 } 00512 00513 params[t].kernel = k; 00514 params[t].result = result; 00515 params[t].start = t*step; 00516 params[t].end = num_vec; 00517 params[t].vec_idx = vec_idx; 00518 params[t].IDX = IDX; 00519 params[t].weights = weights; 00520 params[t].num_suppvec = num_suppvec; 00521 compute_kernel_helper(¶ms[t]); 00522 00523 for (t=0; t<num_threads-1; t++) 00524 pthread_join(threads[t], NULL); 00525 00526 SG_FREE(params); 00527 SG_FREE(threads); 00528 } 00529 #endif 00530 } 00531 } 00532 } 00533 00534 float64_t CCombinedKernel::compute_optimized(int32_t idx) 00535 { 00536 if (!get_is_initialized()) 00537 { 00538 SG_ERROR("CCombinedKernel optimization not initialized\n"); 00539 return 0; 00540 } 00541 00542 float64_t result=0; 00543 00544 CListElement* current=NULL; 00545 CKernel *k=get_first_kernel(current); 00546 while (k) 00547 { 00548 if (k->has_property(KP_LINADD) && 00549 k->get_is_initialized()) 00550 { 00551 if (k->get_combined_kernel_weight()!=0) 00552 { 00553 result += 00554 k->get_combined_kernel_weight()*k->compute_optimized(idx); 00555 } 00556 } 00557 else 00558 { 00559 ASSERT(sv_idx!=NULL || sv_count==0); 00560 ASSERT(sv_weight!=NULL || sv_count==0); 00561 00562 if (k->get_combined_kernel_weight()!=0) 00563 { // compute the usual way for any non-optimized kernel 00564 float64_t sub_result=0; 00565 for (int32_t j=0; j<sv_count; j++) 00566 sub_result += sv_weight[j] * k->kernel(sv_idx[j], idx); 00567 00568 result += k->get_combined_kernel_weight()*sub_result; 00569 } 00570 } 00571 00572 SG_UNREF(k); 00573 k=get_next_kernel(current); 00574 } 00575 00576 return result; 00577 } 00578 00579 void CCombinedKernel::add_to_normal(int32_t idx, float64_t weight) 00580 { 00581 CListElement* current = NULL ; 00582 CKernel* k = get_first_kernel(current); 00583 00584 while(k) 00585 { 00586 k->add_to_normal(idx, weight); 00587 SG_UNREF(k); 00588 k = get_next_kernel(current); 00589 } 00590 set_is_initialized(true) ; 00591 } 00592 00593 void CCombinedKernel::clear_normal() 00594 { 00595 CListElement* current = NULL ; 00596 CKernel* k = get_first_kernel(current); 00597 00598 while(k) 00599 { 00600 k->clear_normal() ; 00601 SG_UNREF(k); 00602 k = get_next_kernel(current); 00603 } 00604 set_is_initialized(true) ; 00605 } 00606 00607 void CCombinedKernel::compute_by_subkernel( 00608 int32_t idx, float64_t * subkernel_contrib) 00609 { 00610 if (append_subkernel_weights) 00611 { 00612 int32_t i=0 ; 00613 CListElement* current = NULL ; 00614 CKernel* k = get_first_kernel(current); 00615 while(k) 00616 { 00617 int32_t num = -1 ; 00618 k->get_subkernel_weights(num); 00619 if (num>1) 00620 k->compute_by_subkernel(idx, &subkernel_contrib[i]) ; 00621 else 00622 subkernel_contrib[i] += k->get_combined_kernel_weight() * k->compute_optimized(idx) ; 00623 00624 SG_UNREF(k); 00625 k = get_next_kernel(current); 00626 i += num ; 00627 } 00628 } 00629 else 00630 { 00631 int32_t i=0 ; 00632 CListElement* current = NULL ; 00633 CKernel* k = get_first_kernel(current); 00634 while(k) 00635 { 00636 if (k->get_combined_kernel_weight()!=0) 00637 subkernel_contrib[i] += k->get_combined_kernel_weight() * k->compute_optimized(idx) ; 00638 00639 SG_UNREF(k); 00640 k = get_next_kernel(current); 00641 i++ ; 00642 } 00643 } 00644 } 00645 00646 const float64_t* CCombinedKernel::get_subkernel_weights(int32_t& num_weights) 00647 { 00648 num_weights = get_num_subkernels() ; 00649 SG_FREE(subkernel_weights_buffer); 00650 subkernel_weights_buffer = SG_MALLOC(float64_t, num_weights); 00651 00652 if (append_subkernel_weights) 00653 { 00654 int32_t i=0 ; 00655 CListElement* current = NULL ; 00656 CKernel* k = get_first_kernel(current); 00657 while(k) 00658 { 00659 int32_t num = -1 ; 00660 const float64_t *w = k->get_subkernel_weights(num); 00661 ASSERT(num==k->get_num_subkernels()); 00662 for (int32_t j=0; j<num; j++) 00663 subkernel_weights_buffer[i+j]=w[j] ; 00664 00665 SG_UNREF(k); 00666 k = get_next_kernel(current); 00667 i += num ; 00668 } 00669 } 00670 else 00671 { 00672 int32_t i=0 ; 00673 CListElement* current = NULL ; 00674 CKernel* k = get_first_kernel(current); 00675 while(k) 00676 { 00677 subkernel_weights_buffer[i] = k->get_combined_kernel_weight(); 00678 00679 SG_UNREF(k); 00680 k = get_next_kernel(current); 00681 i++ ; 00682 } 00683 } 00684 00685 return subkernel_weights_buffer ; 00686 } 00687 00688 SGVector<float64_t> CCombinedKernel::get_subkernel_weights() 00689 { 00690 int32_t num=0; 00691 const float64_t* w=get_subkernel_weights(num); 00692 00693 return SGVector<float64_t>((float64_t*) w, num); 00694 } 00695 00696 void CCombinedKernel::set_subkernel_weights(SGVector<float64_t> weights) 00697 { 00698 if (append_subkernel_weights) 00699 { 00700 int32_t i=0 ; 00701 CListElement* current = NULL ; 00702 CKernel* k = get_first_kernel(current); 00703 while(k) 00704 { 00705 int32_t num = k->get_num_subkernels() ; 00706 ASSERT(i<weights.vlen); 00707 k->set_subkernel_weights(SGVector<float64_t>(&weights.vector[i],num)); 00708 00709 SG_UNREF(k); 00710 k = get_next_kernel(current); 00711 i += num ; 00712 } 00713 } 00714 else 00715 { 00716 int32_t i=0 ; 00717 CListElement* current = NULL ; 00718 CKernel* k = get_first_kernel(current); 00719 while(k) 00720 { 00721 ASSERT(i<weights.vlen); 00722 k->set_combined_kernel_weight(weights.vector[i]); 00723 00724 SG_UNREF(k); 00725 k = get_next_kernel(current); 00726 i++ ; 00727 } 00728 } 00729 } 00730 00731 void CCombinedKernel::set_optimization_type(EOptimizationType t) 00732 { 00733 CKernel* k = get_first_kernel(); 00734 00735 while(k) 00736 { 00737 k->set_optimization_type(t); 00738 00739 SG_UNREF(k); 00740 k = get_next_kernel(); 00741 } 00742 00743 CKernel::set_optimization_type(t); 00744 } 00745 00746 bool CCombinedKernel::precompute_subkernels() 00747 { 00748 CKernel* k = get_first_kernel(); 00749 00750 if (!k) 00751 return false; 00752 00753 CList* new_kernel_list = new CList(true); 00754 00755 while(k) 00756 { 00757 new_kernel_list->append_element(new CCustomKernel(k)); 00758 00759 SG_UNREF(k); 00760 k = get_next_kernel(); 00761 } 00762 00763 SG_UNREF(kernel_list); 00764 kernel_list=new_kernel_list; 00765 SG_REF(kernel_list); 00766 00767 return true; 00768 } 00769 00770 void CCombinedKernel::init() 00771 { 00772 sv_count=0; 00773 sv_idx=NULL; 00774 sv_weight=NULL; 00775 subkernel_weights_buffer=NULL; 00776 initialized=false; 00777 00778 properties |= KP_LINADD | KP_KERNCOMBINATION | KP_BATCHEVALUATION; 00779 kernel_list=new CList(true); 00780 SG_REF(kernel_list); 00781 00782 00783 m_parameters->add((CSGObject**) &kernel_list, "kernel_list", 00784 "List of kernels."); 00785 m_parameters->add_vector(&sv_idx, &sv_count, "sv_idx", 00786 "Support vector index."); 00787 m_parameters->add_vector(&sv_weight, &sv_count, "sv_weight", 00788 "Support vector weights."); 00789 m_parameters->add(&append_subkernel_weights, 00790 "append_subkernel_weights", 00791 "If subkernel weights are appended."); 00792 m_parameters->add(&initialized, "initialized", 00793 "Whether kernel is ready to be used."); 00794 } 00795