/******************************************************************************\
* File: KNN_mutual_information.cpp *
\******************************************************************************/
#include <R.h>
#define MAX_TIES 1000
extern "C"{
void mutinfo(double *XY, const int *kin, const int *n_pts, int* nx, int*ny)
//Mutual Information
{
int d = 2; // Actual Dimension
int n = *n_pts; // Number of Data points
int K = *kin;
int k1, kn;
int *pos = new int[MAX_TIES+K];
double dx, dy, dist;
double *nndist = new double[MAX_TIES+K];
for (int i = 0; i < n; i++) {
kn = K;
for (int k = 0; k < kn; k++) nndist[k] = 0.99 * DBL_MAX;
for (int j = 0; j < n; j++){
if(j == i) continue; //no self-match allowed
dx = fabs(XY[i*d]-XY[j*d]);
dy = fabs(XY[i*d+1]-XY[j*d+1]);
if(dx > dy ) dist = dx;
else dist = dy;
if (dist <= nndist[K - 1] )
for (int k = 0; k <= kn; k++)
if (dist < nndist[k]) {
for (k1 = kn; k1 > k; k1--) {
nndist[k1] = nndist[k1 - 1];
pos[k1] = pos[k1 - 1];
}
nndist[k] = dist;
pos[k] = j;
if (nndist[kn] <= nndist[K - 1]) if (++kn == MAX_TIES - 1) error("too many ties in knn");
break;
}
nndist[kn] = 0.99 * DBL_MAX;
}
nx[i] = 0;
ny[i] = 0;
for (int j = 0; j < n; j++){
//if(j == i) continue; //no self-match allowed
dx = fabs(XY[i*d]-XY[j*d]);
dy = fabs(XY[i*d+1]-XY[j*d+1]);
if(dx < nndist[K-1]) nx[i]++;
if(dy < nndist[K-1]) ny[i]++;
}
}
delete[] pos;
delete[] nndist;
return;
} //end of mutinfo
void mdmutinfo(double *X, double *Y, const int *xdim, const int *ydim, const int *kin, const int *n_pts, int* nx, int*ny)
//Multidimensional Mutual Information
{
int d1 = *xdim; // Actual Dimension
int d2 = *ydim; // Actual Dimension
int n = *n_pts; // Number of Data points
int K = *kin;
int k1, kn;
int *pos = new int[MAX_TIES+K];
double dx, dy, dist, tmp;
double *nndist = new double[MAX_TIES+K];
for (int i = 0; i < n; i++) {
kn = K;
for (int k = 0; k < kn; k++) nndist[k] = 0.99 * DBL_MAX;
for (int j = 0; j < n; j++){
if(j == i) continue; //no self-match allowed
dist = 0.0;
for (int k = 0; k < d1; k++) {
tmp = fabs(X[i*d1+k]-X[j*d1+k]);
if (tmp > dist) dist=tmp;
}
for (int k = 0; k < d2; k++) {
tmp = fabs(Y[i*d2+k]-Y[j*d2+k]);
if (tmp > dist) dist=tmp;
}
if (dist <= nndist[K - 1])
for (int k = 0; k <= kn; k++)
if (dist < nndist[k]) {
for (k1 = kn; k1 > k; k1--) {
nndist[k1] = nndist[k1 - 1];
pos[k1] = pos[k1 - 1];
}
nndist[k] = dist;
pos[k] = j;
if (nndist[kn] <= nndist[K - 1]) if (++kn == MAX_TIES - 1) error("too many ties in knn");
break;
}
nndist[kn] = 0.99 * DBL_MAX;
}
nx[i] = 0;
ny[i] = 0;
for (int j = 0; j < n; j++){
//if(j == i) continue; //no self-match allowed
dx = 0.0;
for (int k = 0; k < d1; k++) {
tmp = fabs(X[i*d1+k]-X[j*d1+k]);
if (tmp > dx) dx=tmp;
}
dy = 0.0;
for (int k = 0; k < d2; k++) {
tmp = fabs(Y[i*d2+k]-Y[j*d2+k]);
if (tmp > dy) dy=tmp;
}
if(dx < nndist[K-1]) nx[i]++;
if(dy < nndist[K-1]) ny[i]++;
}
}
delete[] pos;
delete[] nndist;
return;
} //end of Multidimensional Mutual Information
} //end of extern