25 #include <queso/InfoTheory.h>
34 void distANN_XY(
const ANNpointArray dataX,
const ANNpointArray dataY,
36 unsigned int dimX,
unsigned int dimY,
37 unsigned int xN,
unsigned int yN,
38 unsigned int k,
double eps )
46 nnIdx =
new ANNidx[ k+1 ];
47 nnDist =
new ANNdist[ k+1 ];
48 kdTree =
new ANNkd_tree( dataY, yN, dimY );
51 for(
unsigned int i = 0; i < xN ; i++ )
53 kdTree->annkSearch( dataX[ i ], k+1, nnIdx, nnDist, eps );
55 double my_dist = nnDist[ k ];
61 ANNdistArray nnDist_tmp =
new ANNdist[ yN ];
62 ANNidxArray nnIdx_tmp =
new ANNidx[ yN ];
63 kdTree->annkSearch( dataX[ i ], yN, nnIdx_tmp, nnDist_tmp, eps );
65 for(
unsigned int my_k = k + 1; my_k < yN; ++my_k )
66 if( nnDist_tmp[ my_k ] > 0.0 )
68 my_dist = nnDist_tmp[ my_k ];
75 distsXY[ i ] = my_dist;
92 void normalizeANN_XY( ANNpointArray dataXY,
unsigned int dimXY,
93 ANNpointArray dataX,
unsigned int dimX,
94 ANNpointArray dataY,
unsigned int dimY,
98 ANNpoint meanXY, stdXY;
100 meanXY = annAllocPt(dimXY);
101 stdXY = annAllocPt(dimXY);
104 for(
unsigned int i = 0; i < N; i++ ) {
105 for(
unsigned int j = 0; j < dimX; j++ ) {
106 meanXY[ j ] += dataXY[ i ][ j ];
108 for(
unsigned int j = 0; j < dimY; j++ ) {
109 meanXY[ dimX + j ] += dataXY[ i ][ dimX + j ];
112 for(
unsigned int j = 0; j < dimXY; j++ ) {
113 meanXY[ j ] = meanXY[ j ] / (double)N;
117 for(
unsigned int i = 0; i < N; i++ ) {
118 for(
unsigned int j = 0; j < dimXY; j++ ) {
119 stdXY[ j ] += pow( dataXY[ i ][ j ] - meanXY[ j ], 2.0 );
122 for(
unsigned int j = 0; j < dimXY; j++ ) {
123 stdXY[ j ] = sqrt( stdXY[ j ] / ((
double)N-1.0) );
135 for(
unsigned int i = 0; i < N; i++ ) {
137 for(
unsigned int j = 0; j < dimXY; j++ ) {
138 dataXY[ i ][ j ] = ( dataXY[ i ][ j ] - meanXY[ j ] ) / stdXY[ j ];
142 for(
unsigned int j = 0; j < dimX; j++ ) {
143 dataX[ i ][ j ] = dataXY[ i ][ j ];
145 for(
unsigned int j = 0; j < dimY; j++ ) {
146 dataY[ i ][ j ] = dataXY[ i ][ dimX + j ];
155 double computeMI_ANN( ANNpointArray dataXY,
156 unsigned int dimX,
unsigned int dimY,
157 unsigned int k,
unsigned int N,
double eps )
160 ANNpointArray dataX, dataY;
166 unsigned int dimXY = dimX + dimY;
169 dataX = annAllocPts(N,dimX);
170 dataY = annAllocPts(N,dimY);
171 distsXY =
new double[N];
174 normalizeANN_XY( dataXY, dimXY, dataX, dimX, dataY, dimY, N);
177 kdTreeX =
new ANNkd_tree( dataX, N, dimX );
178 kdTreeY =
new ANNkd_tree( dataY, N, dimY );
179 distANN_XY( dataXY, dataXY, distsXY, dimXY, dimXY, N, N, k, eps );
182 double marginal_contrib = 0.0;
183 for(
unsigned int i = 0; i < N; i++ ) {
185 int no_pts_X = kdTreeX->annkFRSearch( dataX[ i ], distsXY[ i ], 0, NULL, NULL, eps);
186 int no_pts_Y = kdTreeY->annkFRSearch( dataY[ i ], distsXY[ i ], 0, NULL, NULL, eps);
188 marginal_contrib += gsl_sf_psi_int( no_pts_X+1 ) + gsl_sf_psi_int( no_pts_Y+1 );
190 MI_est = gsl_sf_psi_int( k ) + gsl_sf_psi_int( N ) - marginal_contrib / (double)N;
196 annDeallocPts( dataX );
197 annDeallocPts( dataY );
207 template<
template <
class P_V,
class P_M>
class RV,
class P_V,
class P_M>
208 double estimateMI_ANN(
const RV<P_V,P_M>& jointRV,
209 const unsigned int xDimSel[],
unsigned int dimX,
210 const unsigned int yDimSel[],
unsigned int dimY,
211 unsigned int k,
unsigned int N,
double eps )
213 ANNpointArray dataXY;
216 unsigned int dimXY = dimX + dimY;
219 dataXY = annAllocPts(N,dimXY);
222 P_V smpRV( jointRV.imageSet().vectorSpace().zeroVector() );
223 for(
unsigned int i = 0; i < N; i++ ) {
225 jointRV.realizer().realization( smpRV );
228 for(
unsigned int j = 0; j < dimX; j++ ) {
229 dataXY[ i ][ j ] = smpRV[ xDimSel[j] ];
231 for(
unsigned int j = 0; j < dimY; j++ ) {
232 dataXY[ i ][ dimX + j ] = smpRV[ yDimSel[j] ];
237 MI_est = computeMI_ANN( dataXY,
242 annDeallocPts( dataXY );
251 template<
class P_V,
class P_M,
252 template <
class P_V,
class P_M>
class RV_1,
253 template <
class P_V,
class P_M>
class RV_2>
254 double estimateMI_ANN(
const RV_1<P_V,P_M>& xRV,
255 const RV_2<P_V,P_M>& yRV,
256 const unsigned int xDimSel[],
unsigned int dimX,
257 const unsigned int yDimSel[],
unsigned int dimY,
258 unsigned int k,
unsigned int N,
double eps )
260 ANNpointArray dataXY;
263 unsigned int dimXY = dimX + dimY;
266 dataXY = annAllocPts(N,dimXY);
269 P_V smpRV_x( xRV.imageSet().vectorSpace().zeroVector() );
270 P_V smpRV_y( yRV.imageSet().vectorSpace().zeroVector() );
272 for(
unsigned int i = 0; i < N; i++ ) {
274 xRV.realizer().realization( smpRV_x );
275 yRV.realizer().realization( smpRV_y );
278 for(
unsigned int j = 0; j < dimX; j++ ) {
279 dataXY[ i ][ j ] = smpRV_x[ xDimSel[j] ];
281 for(
unsigned int j = 0; j < dimY; j++ ) {
282 dataXY[ i ][ dimX + j ] = smpRV_y[ yDimSel[j] ];
287 MI_est = computeMI_ANN( dataXY,
292 annDeallocPts( dataXY );
301 template <
class P_V,
class P_M,
302 template <
class P_V,
class P_M>
class RV_1,
303 template <
class P_V,
class P_M>
class RV_2>
304 double estimateKL_ANN( RV_1<P_V,P_M>& xRV,
306 unsigned int xDimSel[],
unsigned int dimX,
307 unsigned int yDimSel[],
unsigned int dimY,
308 unsigned int xN,
unsigned int yN,
309 unsigned int k,
double eps )
319 std::cout <<
"Error-KL: the dimensions should agree" << std::endl;
324 dataX = annAllocPts( xN, dimX );
325 dataY = annAllocPts( yN, dimY );
326 distsX =
new double[xN];
327 distsXY =
new double[xN];
330 P_V xSmpRV( xRV.imageSet().vectorSpace().zeroVector() );
331 for(
unsigned int i = 0; i < xN; i++ ) {
333 xRV.realizer().realization( xSmpRV );
335 for(
unsigned int j = 0; j < dimX; j++ ) {
336 dataX[ i ][ j ] = xSmpRV[ xDimSel[j] ];
341 P_V ySmpRV( yRV.imageSet().vectorSpace().zeroVector() );
342 for(
unsigned int i = 0; i < yN; i++ ) {
344 yRV.realizer().realization( ySmpRV );
346 for(
unsigned int j = 0; j < dimY; j++ ) {
347 dataY[ i ][ j ] = ySmpRV[ yDimSel[j] ];
352 distANN_XY( dataX, dataX, distsX, dimX, dimX, xN, xN, k+1, eps );
353 distANN_XY( dataX, dataY, distsXY, dimX, dimY, xN, yN, k, eps );
356 double sum_log_ratio = 0.0;
357 for(
unsigned int i = 0; i < xN; i++ )
359 sum_log_ratio += log( distsXY[i] / distsX[i] );
361 KL_est = (double)dimX/(
double)xN * sum_log_ratio + log( (
double)yN / ((
double)xN-1.0 ) );
364 annDeallocPts( dataX );
365 annDeallocPts( dataY );
377 template <
class P_V,
class P_M,
378 template <
class P_V,
class P_M>
class RV_1,
379 template <
class P_V,
class P_M>
class RV_2>
380 double estimateCE_ANN( RV_1<P_V,P_M>& xRV,
382 unsigned int xDimSel[],
unsigned int dimX,
383 unsigned int yDimSel[],
unsigned int dimY,
384 unsigned int xN,
unsigned int yN,
385 unsigned int k,
double eps )
395 std::cout <<
"Error-CE: the dimensions should agree" << std::endl;
400 dataX = annAllocPts( xN, dimX );
401 dataY = annAllocPts( yN, dimY );
402 distsXY =
new double[xN];
403 kdTree =
new ANNkd_tree( dataY, yN, dimY );
406 P_V xSmpRV( xRV.imageSet().vectorSpace().zeroVector() );
407 for(
unsigned int i = 0; i < xN; i++ ) {
409 xRV.realizer().realization( xSmpRV );
411 for(
unsigned int j = 0; j < dimX; j++ ) {
412 dataX[ i ][ j ] = xSmpRV[ xDimSel[j] ];
417 P_V ySmpRV( yRV.imageSet().vectorSpace().zeroVector() );
418 for(
unsigned int i = 0; i < yN; i++ ) {
420 yRV.realizer().realization( ySmpRV );
422 for(
unsigned int j = 0; j < dimY; j++ ) {
423 dataY[ i ][ j ] = ySmpRV[ yDimSel[j] ];
428 distANN_XY( dataX, dataY, distsXY, dimX, dimY, xN, yN, k, eps );
429 kdTree =
new ANNkd_tree( dataY, yN, dimY );
432 double sum_log = 0.0;
433 for(
unsigned int i = 0; i < xN; i++ )
435 sum_log += log( distsXY[i] );
437 CE_est = (double)dimX/(
double)xN * sum_log + log( (
double)yN ) - gsl_sf_psi_int( k );
440 annDeallocPts( dataX );
441 annDeallocPts( dataY );
449 #endif // QUESO_HAS_ANN