PyramidChi2.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) 2008-2009 Alexander Binder
00008  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00009  */
00010 
00011 #include <shogun/kernel/PyramidChi2.h>
00012 #include <shogun/lib/common.h>
00013 #include <shogun/kernel/GaussianKernel.h>
00014 #include <shogun/features/Features.h>
00015 #include <shogun/io/SGIO.h>
00016 #include <shogun/mathematics/Math.h>
00017 
00018 using namespace shogun;
00019 
00020 CPyramidChi2::CPyramidChi2()
00021 : weights(NULL)
00022 {
00023     // this will produce an erro in kernel computation!
00024     num_cells=0;
00025     width_computation_type=0;
00026     width=1;
00027     num_randfeats_forwidthcomputation=-1;
00028 }
00029 
00030 CPyramidChi2::CPyramidChi2(
00031     int32_t size, int32_t num_cells2,
00032         float64_t* weights_foreach_cell2,
00033         int32_t width_computation_type2,
00034         float64_t width2)
00035 : CDotKernel(size), num_cells(num_cells2),weights(NULL),
00036 width_computation_type(width_computation_type2), width(width2),
00037      num_randfeats_forwidthcomputation(-1)
00038 {
00039     if(num_cells<=0)
00040         SG_ERROR("CPyramidChi2 Constructor fatal error: parameter num_cells2 NOT positive");
00041     weights=SG_MALLOC(float64_t, num_cells);
00042     if(weights_foreach_cell2)
00043     {
00044         for (int32_t i=0; i<num_cells; ++i)
00045             weights[i]=weights_foreach_cell2[i];
00046     }
00047     else
00048     {   for (int32_t i=0; i<num_cells; ++i)
00049             weights[i]=1;
00050     }
00051 
00052     if (width_computation_type>0 )
00053     {
00054         num_randfeats_forwidthcomputation=(int32_t)CMath::round(width);
00055         width=-1;
00056     }
00057 
00058 
00059 }
00060 
00061 void CPyramidChi2::cleanup()
00062 {
00063     // this will produce an erro in kernel computation!
00064     num_cells=0;
00065     width_computation_type=0;
00066     width=1;
00067 
00068     num_randfeats_forwidthcomputation=-1;
00069 
00070     SG_FREE(weights);
00071     weights=NULL;
00072 
00073     CKernel::cleanup();
00074 }
00075 
00076 bool CPyramidChi2::init(CFeatures* l, CFeatures* r)
00077 {
00078     CDotKernel::init(l, r);
00079     return init_normalizer();
00080 }
00081 
00082 CPyramidChi2::CPyramidChi2(
00083     CDenseFeatures<float64_t>* l, CDenseFeatures<float64_t>* r,
00084         int32_t size, int32_t num_cells2,
00085         float64_t* weights_foreach_cell2,
00086         int32_t width_computation_type2,
00087         float64_t width2)
00088 : CDotKernel(size), num_cells(num_cells2), weights(NULL),
00089 width_computation_type(width_computation_type2), width(width2),
00090       num_randfeats_forwidthcomputation(-1)
00091 {
00092     if(num_cells<=0)
00093         SG_ERROR("CPyramidChi2 Constructor fatal error: parameter num_cells2 NOT positive");
00094     weights=SG_MALLOC(float64_t, num_cells);
00095     if(weights_foreach_cell2)
00096     {
00097         for (int32_t i=0; i<num_cells; ++i)
00098             weights[i]=weights_foreach_cell2[i];
00099     }
00100     else
00101     {   for (int32_t i=0; i<num_cells; ++i)
00102             weights[i]=1;
00103     }
00104 
00105     if (width_computation_type>0 )
00106     {
00107         num_randfeats_forwidthcomputation=(int32_t)CMath::round(width);
00108         width=-1;
00109     }
00110 
00111     init(l, r);
00112 }
00113 
00114 CPyramidChi2::~CPyramidChi2()
00115 {
00116     cleanup();
00117 }
00118 
00119 
00120 
00121 float64_t CPyramidChi2::compute(int32_t idx_a, int32_t idx_b)
00122 {
00123 
00124     if(num_cells<=0)
00125         SG_ERROR("CPyramidChi2::compute(...) fatal error: parameter num_cells NOT positive");
00126 
00127     int32_t alen, blen;
00128     bool afree, bfree;
00129 
00130     float64_t* avec=((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a,
00131                     alen, afree);
00132     float64_t* bvec=((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b,
00133                     blen, bfree);
00134     if(alen!=blen)
00135         SG_ERROR("CPyramidChi2::compute(...) fatal error: lhs feature dim != rhs feature dim");
00136 
00137     int32_t dims=alen/num_cells;
00138 
00139 
00140     if(width<=0)
00141     {
00142         if(width_computation_type >0)
00143         {
00144 
00145             //compute width
00146             int32_t numind;
00147 
00148             if (num_randfeats_forwidthcomputation >1)
00149             {
00150                 numind=CMath::min( ((CDenseFeatures<float64_t>*) lhs)->get_num_vectors() , num_randfeats_forwidthcomputation);
00151             }
00152             else
00153             {
00154                 numind= ((CDenseFeatures<float64_t>*) lhs)->get_num_vectors();
00155             }
00156             float64_t* featindices = SG_MALLOC(float64_t, numind);
00157 
00158             if (num_randfeats_forwidthcomputation >0)
00159             {
00160                 for(int32_t i=0; i< numind;++i)
00161                     featindices[i]=CMath::random(0, ((CDenseFeatures<float64_t>*) lhs)->get_num_vectors()-1);
00162             }
00163             else
00164             {
00165                 for(int32_t i=0; i< numind;++i)
00166                     featindices[i]=i;
00167             }
00168 
00169 
00170             width=0;
00171 
00172             //get avec, get bvec    only from lhs, do not free
00173             for (int32_t li=0; li < numind;++li)
00174             {
00175                 avec=((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(featindices[li],
00176                     alen, afree);
00177                 for (int32_t ri=0; ri <=li;++ri)
00178                 {
00179                     // lhs is right here!!!
00180                     bvec=((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(featindices[ri],
00181                             blen, bfree);
00182 
00183                     float64_t result=0;
00184                     for (int32_t histoind=0; histoind<num_cells; ++histoind)
00185                     {
00186                         float64_t curweight=weights[histoind];
00187 
00188                         for (int32_t i=0; i< dims; ++i)
00189                         {
00190                             int32_t index= histoind*dims+i;
00191                             if(avec[index] + bvec[index]>0)
00192                             {
00193                                 result+= curweight*(avec[index] - bvec[index])*(avec[index]
00194                                     - bvec[index])/(avec[index] + bvec[index]);
00195                             }
00196                         }
00197                     }
00198                     width+=result*2.0/((double)numind)/(numind+1.0);
00199                 }
00200 
00201             }
00202             SG_FREE(featindices);
00203         }
00204         else
00205         {
00206             SG_ERROR("CPyramidChi2::compute(...) fatal error: width<=0");
00207         }
00208     }
00209 
00210 
00211     //the actual kernel computation
00212     avec=((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a,
00213                     alen, afree);
00214     bvec=((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b,
00215                     blen, bfree);
00216 
00217     float64_t result=0;
00218     for (int32_t histoind=0; histoind<num_cells; ++histoind)
00219     {
00220         float64_t curweight=weights[histoind];
00221 
00222         for (int32_t i=0; i< dims; ++i)
00223         {
00224             int32_t index= histoind*dims+i;
00225             if(avec[index] + bvec[index]>0)
00226             {
00227                 result+= curweight*(avec[index] - bvec[index])*(avec[index]
00228                     - bvec[index])/(avec[index] + bvec[index]);
00229             }
00230         }
00231     }
00232     result= CMath::exp(-result/width);
00233 
00234 
00235     ((CDenseFeatures<float64_t>*) lhs)->free_feature_vector(avec, idx_a, afree);
00236     ((CDenseFeatures<float64_t>*) rhs)->free_feature_vector(bvec, idx_b, bfree);
00237 
00238     return (result);
00239 }
00240 
00241 void CPyramidChi2::setparams_pychi2(int32_t num_cells2,
00242         float64_t* weights_foreach_cell2,
00243         int32_t width_computation_type2,
00244         float64_t width2)
00245 {
00246     num_cells=num_cells2;
00247     width_computation_type=width_computation_type2;
00248     width=width2;
00249     num_randfeats_forwidthcomputation=-1;
00250 
00251     if(num_cells<=0)
00252         SG_ERROR("CPyramidChi2::setparams_pychi2(...) fatal error: parameter num_cells2 NOT positive");
00253     if(weights)
00254         SG_FREE(weights);
00255     weights=SG_MALLOC(float64_t, num_cells);
00256     if(weights_foreach_cell2)
00257     {
00258         for (int32_t i=0; i<num_cells; ++i)
00259             weights[i]=weights_foreach_cell2[i];
00260     }
00261     else
00262     {   for (int32_t i=0; i<num_cells; ++i)
00263             weights[i]=1;
00264     }
00265 
00266     if (width_computation_type>0 )
00267     {
00268         num_randfeats_forwidthcomputation=(int32_t)CMath::round(width);
00269         width=-1;
00270     }
00271 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation