CombinedKernel.cpp

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

SHOGUN Machine Learning Toolbox - Documentation