SHOGUN  v3.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ProductKernel.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  * Copyright (C) 2012 Jacob Walker
00008  *
00009  * Code adapted from CCombinedKernel
00010  */
00011 
00012 #include <shogun/kernel/ProductKernel.h>
00013 #include <shogun/kernel/CustomKernel.h>
00014 
00015 using namespace shogun;
00016 
00017 CProductKernel::CProductKernel(int32_t size) : CKernel(size)
00018 {
00019     init();
00020 
00021     SG_INFO("Product kernel created (%p)\n", this)
00022 }
00023 
00024 CProductKernel::~CProductKernel()
00025 {
00026     cleanup();
00027     SG_UNREF(kernel_array);
00028 
00029     SG_INFO("Product kernel deleted (%p).\n", this)
00030 }
00031 
00032 //Adapted from CCombinedKernel
00033 bool CProductKernel::init(CFeatures* l, CFeatures* r)
00034 {
00035     CKernel::init(l,r);
00036     ASSERT(l->get_feature_class()==C_COMBINED)
00037     ASSERT(r->get_feature_class()==C_COMBINED)
00038     ASSERT(l->get_feature_type()==F_UNKNOWN)
00039     ASSERT(r->get_feature_type()==F_UNKNOWN)
00040 
00041     CFeatures* lf=NULL;
00042     CFeatures* rf=NULL;
00043     CKernel* k=NULL;
00044 
00045     bool result=true;
00046 
00047     index_t f_idx=0;
00048     for (index_t k_idx=0; k_idx<get_num_subkernels() && result; k_idx++)
00049     {
00050         k=get_kernel(k_idx);
00051         if (!k)
00052             SG_ERROR("Kernel at position %d is NULL\n", k_idx);
00053 
00054         // skip over features - the custom kernel does not need any
00055         if (k->get_kernel_type() != K_CUSTOM)
00056         {
00057             lf=((CCombinedFeatures*) l)->get_feature_obj(f_idx);
00058             rf=((CCombinedFeatures*) r)->get_feature_obj(f_idx);
00059             f_idx++;
00060             if (!lf || !rf)
00061             {
00062                 SG_UNREF(lf);
00063                 SG_UNREF(rf);
00064                 SG_UNREF(k);
00065                 SG_ERROR("ProductKernel: Number of features/kernels does not match - bailing out\n")
00066             }
00067 
00068             SG_DEBUG("Initializing 0x%p - \"%s\"\n", this, k->get_name())
00069             result=k->init(lf,rf);
00070 
00071             SG_UNREF(lf);
00072             SG_UNREF(rf);
00073 
00074             if (!result)
00075                 break;
00076         }
00077         else
00078         {
00079             SG_DEBUG("Initializing 0x%p - \"%s\" (skipping init, this is a CUSTOM kernel)\n", this, k->get_name())
00080             if (!k->has_features())
00081                 SG_ERROR("No kernel matrix was assigned to this Custom kernel\n")
00082             if (k->get_num_vec_lhs() != num_lhs)
00083                 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())
00084             if (k->get_num_vec_rhs() != num_rhs)
00085                 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())
00086         }
00087 
00088         SG_UNREF(k);
00089     }
00090 
00091     if (!result)
00092     {
00093         SG_INFO("ProductKernel: Initialising the following kernel failed\n")
00094         if (k)
00095         {
00096             k->list_kernel();
00097             SG_UNREF(k);
00098         }
00099         else
00100             SG_INFO("<NULL>\n")
00101         return false;
00102     }
00103 
00104     if ( (f_idx!=((CCombinedFeatures*) l)->get_num_feature_obj()) ||
00105             (f_idx!=((CCombinedFeatures*) r)->get_num_feature_obj()) )
00106         SG_ERROR("ProductKernel: Number of features/kernels does not match - bailing out\n")
00107 
00108     initialized=true;
00109     return true;
00110 }
00111 
00112 //Adapted from CCombinedKernel
00113 void CProductKernel::remove_lhs()
00114 {
00115     for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
00116     {
00117         CKernel* k=get_kernel(k_idx);
00118         if (k->get_kernel_type() != K_CUSTOM)
00119             k->remove_lhs();
00120 
00121         SG_UNREF(k);
00122     }
00123     CKernel::remove_lhs();
00124 
00125     num_lhs=0;
00126 }
00127 
00128 //Adapted from CCombinedKernel
00129 void CProductKernel::remove_rhs()
00130 {
00131     for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
00132     {
00133         CKernel* k=get_kernel(k_idx);
00134         if (k->get_kernel_type() != K_CUSTOM)
00135             k->remove_rhs();
00136         SG_UNREF(k);
00137     }
00138     CKernel::remove_rhs();
00139 
00140     num_rhs=0;
00141 }
00142 
00143 //Adapted from CCombinedKernel
00144 void CProductKernel::remove_lhs_and_rhs()
00145 {
00146     for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
00147     {
00148         CKernel* k=get_kernel(k_idx);
00149         if (k->get_kernel_type() != K_CUSTOM)
00150             k->remove_lhs_and_rhs();
00151         SG_UNREF(k);
00152     }
00153 
00154     CKernel::remove_lhs_and_rhs();
00155 
00156     num_lhs=0;
00157     num_rhs=0;
00158 }
00159 
00160 //Adapted from CCombinedKernel
00161 void CProductKernel::cleanup()
00162 {
00163     for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
00164     {
00165         CKernel* k=get_kernel(k_idx);
00166         k->cleanup();
00167         SG_UNREF(k);
00168     }
00169 
00170     CKernel::cleanup();
00171 
00172     num_lhs=0;
00173     num_rhs=0;
00174 }
00175 
00176 //Adapted from CCombinedKernel
00177 void CProductKernel::list_kernels()
00178 {
00179     SG_INFO("BEGIN PRODUCT KERNEL LIST - ")
00180     this->list_kernel();
00181 
00182     for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
00183     {
00184         CKernel* k=get_kernel(k_idx);
00185         k->list_kernel();
00186         SG_UNREF(k);
00187     }
00188     SG_INFO("END PRODUCT KERNEL LIST - ")
00189 }
00190 
00191 //Adapted from CCombinedKernel
00192 float64_t CProductKernel::compute(int32_t x, int32_t y)
00193 {
00194     float64_t result=1;
00195     for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
00196     {
00197         CKernel* k=get_kernel(k_idx);
00198         result *= k->get_combined_kernel_weight() * k->kernel(x,y);
00199         SG_UNREF(k);
00200     }
00201 
00202     return result;
00203 }
00204 
00205 //Adapted from CCombinedKernel
00206 bool CProductKernel::precompute_subkernels()
00207 {
00208     if (get_num_subkernels()==0)
00209         return false;
00210 
00211     CDynamicObjectArray* new_kernel_array=new CDynamicObjectArray();
00212 
00213     for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
00214     {
00215         CKernel* k=get_kernel(k_idx);
00216         new_kernel_array->append_element(new CCustomKernel(k));
00217         SG_UNREF(k);
00218     }
00219 
00220     SG_UNREF(kernel_array);
00221     kernel_array=new_kernel_array;
00222     SG_REF(kernel_array);
00223 
00224     return true;
00225 }
00226 
00227 void CProductKernel::init()
00228 {
00229     initialized=false;
00230 
00231     properties=KP_NONE;
00232     kernel_array=new CDynamicObjectArray();
00233     SG_REF(kernel_array);
00234 
00235     SG_ADD((CSGObject**) &kernel_array, "kernel_array", "Array of kernels",
00236         MS_AVAILABLE);
00237     SG_ADD(&initialized, "initialized", "Whether kernel is ready to be used",
00238         MS_NOT_AVAILABLE);
00239 }
00240 
00241 SGMatrix<float64_t> CProductKernel::get_parameter_gradient(
00242         const TParameter* param, index_t index)
00243 {
00244     CKernel* k=get_kernel(0);
00245     SGMatrix<float64_t> temp_kernel=k->get_kernel_matrix();
00246     SG_UNREF(k);
00247 
00248     bool found_derivative=false;
00249 
00250     for (index_t g=0; g<temp_kernel.num_rows; g++)
00251     {
00252         for (int h=0; h<temp_kernel.num_cols; h++)
00253             temp_kernel(g,h)=1.0;
00254     }
00255 
00256     for (index_t k_idx=0; k_idx<get_num_subkernels(); k_idx++)
00257     {
00258         k=get_kernel(k_idx);
00259         SGMatrix<float64_t> cur_matrix=k->get_kernel_matrix();
00260         SGMatrix<float64_t> derivative=
00261             k->get_parameter_gradient(param, index);
00262 
00263         if (derivative.num_cols*derivative.num_rows > 0)
00264         {
00265             found_derivative=true;
00266             for (index_t g=0; g<derivative.num_rows; g++)
00267             {
00268                 for (index_t h=0; h<derivative.num_cols; h++)
00269                     temp_kernel(g,h)*=derivative(g,h);
00270             }
00271         }
00272         else
00273         {
00274             for (index_t g=0; g<cur_matrix.num_rows; g++)
00275             {
00276                 for (index_t h=0; h<cur_matrix.num_cols; h++)
00277                     temp_kernel(g,h)*=cur_matrix(g,h);
00278             }
00279         }
00280 
00281         SG_UNREF(k);
00282     }
00283 
00284     if (found_derivative)
00285         return temp_kernel;
00286     else
00287         return SGMatrix<float64_t>();
00288 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation