00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
00346
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
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 {
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 {
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