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