00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "PyramidChi2.h"
00012 #include "lib/common.h"
00013 #include "kernel/GaussianKernel.h"
00014 #include "features/Features.h"
00015 #include "features/RealFeatures.h"
00016 #include "lib/io.h"
00017
00018 CPyramidChi2::CPyramidChi2(
00019 int32_t size, float64_t width2, int32_t* pyramidlevels2,int32_t
00020 numlevels2, int32_t numbinsinhistogram2, float64_t* weights2,
00021 int32_t numweights2)
00022 : CSimpleKernel<float64_t>(size), width(width2), pyramidlevels(NULL),
00023 numlevels(numlevels2), weights(NULL), numweights(numweights2)
00024 {
00025 pyramidlevels=new int32_t[numlevels];
00026 for(int32_t i=0; i<numlevels; ++i)
00027 pyramidlevels[i]=pyramidlevels2[i];
00028
00029 numbinsinhistogram=numbinsinhistogram2;
00030
00031 weights=new float64_t[numweights];
00032 for(int32_t i=0; i<numweights; ++i)
00033 weights[i]=weights2[i];
00034
00035 if (!sanitycheck_weak())
00036 SG_ERROR("CPyramidChi2::CPyramidChi2(... first constructor): false==sanitycheck_weak() occurred! Someone messed up the initializing of the kernel.\0");
00037 }
00038
00039 void CPyramidChi2::cleanup()
00040 {
00041
00042
00043 numlevels=-1;
00044 numweights=-1;
00045 numbinsinhistogram=-1;
00046
00047
00048 delete[] pyramidlevels;
00049 pyramidlevels=NULL;
00050 delete[] weights;
00051 weights=NULL;
00052
00053 CKernel::cleanup();
00054 }
00055
00056 bool CPyramidChi2::init(CFeatures* l, CFeatures* r)
00057 {
00058 CSimpleKernel<float64_t>::init(l, r);
00059 return init_normalizer();
00060 }
00061
00062 CPyramidChi2::CPyramidChi2(
00063 CRealFeatures* l, CRealFeatures* r, int32_t size, float64_t width2,
00064 int32_t* pyramidlevels2,int32_t numlevels2, int32_t numbinsinhistogram2,
00065 float64_t* weights2,int32_t numweights2)
00066 : CSimpleKernel<float64_t>(size), width(width2), pyramidlevels(NULL),
00067 numlevels(numlevels2), weights(NULL), numweights(numweights2)
00068 {
00069 pyramidlevels=new int32_t[numlevels];
00070 for(int32_t i=0; i<numlevels;++i )
00071 pyramidlevels[i]=pyramidlevels2[i];
00072
00073 numbinsinhistogram=numbinsinhistogram2;
00074
00075 weights=new float64_t[numweights];
00076 for(int32_t i=0; i<numweights;++i )
00077 weights[i]=weights2[i];
00078
00079 if(!sanitycheck_weak())
00080 SG_ERROR("CPyramidChi2::CPyramidChi2(... second constructor): false==sanitycheck_weak() occurred! Someone messed up with initializing the kernel.\0");
00081
00082 init(l, r);
00083 }
00084
00085 CPyramidChi2::~CPyramidChi2()
00086 {
00087 cleanup();
00088 }
00089
00090 bool CPyramidChi2::load_init(FILE* src)
00091 {
00092 return (false);
00093 }
00094
00095 bool CPyramidChi2::save_init(FILE* dest)
00096 {
00097 return (false);
00098 }
00099
00100
00101 bool CPyramidChi2::sanitycheck_weak()
00102 {
00103 if (numbinsinhistogram<=0)
00104 {
00105 SG_ERROR("bool CPyramidChi2::sanitycheck_weak(): member value inconsistencer: numbinsinhistogram<=0");
00106 return (false);
00107 }
00108
00109 if ((pyramidlevels!=NULL) && (numlevels<=0))
00110 {
00111 SG_ERROR("void CPyramidChi2::sanitycheck_weak(): inconsistency found: (pyramidlevels!=NULL) && (numlevels <=0)");
00112
00113 return(false);
00114 }
00115
00116 if ((pyramidlevels==NULL) && (numlevels>0))
00117 {
00118 SG_ERROR("void CPyramidChi2::sanitycheck_weak(): inconsistency found: (pyramidlevels==NULL) && (numlevels>0)");
00119
00120 return(false);
00121 }
00122
00123 if((weights!=NULL) &&(numweights<=0))
00124 {
00125 SG_ERROR("void CPyramidChi2::sanitycheck_weak(): inconsistency found: (weights!=NULL) && (numweights <=0)");
00126
00127 return(false);
00128 }
00129
00130 if ((weights==NULL) && (numweights>0))
00131 {
00132 SG_ERROR("void CPyramidChi2::sanitycheck_weak(): inconsistency found: (weights==NULL) && (numweights >0)");
00133
00134 return(false);
00135 }
00136
00137
00138 int32_t sum=0;
00139 for (int32_t levelind=0; levelind < numlevels; ++levelind)
00140 {
00141 sum+=CMath::pow(4, pyramidlevels[levelind]);
00142 }
00143
00144 if (sum!=numweights )
00145 {
00146 SG_ERROR("bool CPyramidChi2::sanitycheck_weak(): member value error: sum!=numweights ");
00147 return (false);
00148 }
00149
00150 return (true);
00151
00152 }
00153
00154
00155 float64_t CPyramidChi2::compute(int32_t idx_a, int32_t idx_b)
00156 {
00157
00158
00159
00160
00161
00162
00163
00164
00165 int32_t alen, blen;
00166 bool afree, bfree;
00167
00168 float64_t* avec=
00169 ((CRealFeatures*) lhs)->get_feature_vector(idx_a,
00170 alen, afree);
00171 float64_t* bvec=
00172 ((CRealFeatures*) rhs)->get_feature_vector(idx_b,
00173 blen, bfree);
00174 ASSERT(alen==blen);
00175
00176 int32_t dims=0;
00177 for (int32_t levelind=0; levelind<numlevels; ++levelind)
00178 {
00179 dims+=CMath::pow(4, pyramidlevels[levelind])*numbinsinhistogram;
00180 }
00181 ASSERT(dims==alen);
00182
00183
00184 float64_t result=0;
00185 int32_t cursum=0;
00186
00187 for (int32_t lvlind=0; lvlind< numlevels; ++lvlind)
00188 {
00189 for (int32_t histoind=0; histoind<CMath::pow(4, pyramidlevels[lvlind]); ++histoind)
00190 {
00191 float64_t curweight=weights[cursum+histoind];
00192
00193 for (int32_t i=0; i< numbinsinhistogram; ++i)
00194 {
00195 int32_t index= (cursum+histoind)*numbinsinhistogram+i;
00196 if(avec[index] + bvec[index]>0)
00197 {
00198 result+= curweight*(avec[index] - bvec[index])*(avec[index]
00199 - bvec[index])/(avec[index] + bvec[index]);
00200 }
00201 }
00202 }
00203 cursum+=CMath::pow(4, pyramidlevels[lvlind]);
00204 }
00205 result=exp(-result/(float64_t)width);
00206
00207
00208 ((CRealFeatures*) lhs)->free_feature_vector(avec, idx_a, afree);
00209 ((CRealFeatures*) rhs)->free_feature_vector(bvec, idx_b, bfree);
00210
00211 return (result);
00212 }
00213
00214
00215 void CPyramidChi2::setstandardweights()
00216 {
00217 int32_t sum=0;
00218 int32_t maxlvl=0;
00219 for (int32_t levelind=0; levelind < numlevels; ++levelind)
00220 {
00221 sum+=CMath::pow(4, pyramidlevels[levelind]);
00222 maxlvl=CMath::max(maxlvl,pyramidlevels[levelind]);
00223 }
00224
00225 if (weights==NULL)
00226 {
00227 numweights=sum;
00228 weights=new float64_t[numweights];
00229 }
00230
00231 else if (numweights!=sum)
00232 {
00233
00234 if (numweights>0)
00235 {
00236 delete[] weights;
00237 }
00238 else
00239 {
00240 SG_ERROR("void CPyramidChi2::setstandardweights(): inconsistency found: (weights!=NULL) && (numweights <=0), continuing, but memory leak possible");
00241 }
00242
00243 numweights=sum;
00244 weights=new float64_t[numweights];
00245 }
00246
00247
00248 int32_t cursum=0;
00249 for (int32_t levelind=0; levelind < numlevels; ++levelind)
00250 {
00251 if (pyramidlevels[levelind]==0)
00252 {
00253 for (int32_t histoind=0; histoind<CMath::pow(4, pyramidlevels[levelind]); ++histoind)
00254 {
00255 weights[cursum+histoind]=CMath::pow((float64_t)2.0,
00256 -(float64_t)maxlvl);
00257 }
00258 }
00259 else
00260 {
00261 for (int32_t histoind=0; histoind<CMath::pow(4, pyramidlevels[levelind]); ++histoind)
00262 {
00263 weights[cursum+histoind]=CMath::pow((float64_t)2.0,
00264 (float64_t)(pyramidlevels[levelind]-1-maxlvl));
00265 }
00266 }
00267 cursum+=CMath::pow(4, pyramidlevels[levelind]);
00268 }
00269 }