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

SHOGUN Machine Learning Toolbox - Documentation