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