Ran myran=new Ran(17);
// Test KDtree in 2D
for (i=0;i<N;i++) {
kd2[i] = new Point(2);
kd2[i].x[0]=myran.doub();
kd2[i].x[1]=myran.doub();
}
KDtree tree2=new KDtree(2,kd2);
// Test locate(Point) method
Point y=new Point(2);
int nb; // number of box containing y
localflag=false;
for (i=0;i<M;i++) {
y.x[0]=myran.doub();
y.x[1]=myran.doub();
nb=tree2.locate(y);
// System.out.printf(nb);
// System.out.printf(tree2.boxes[nb].lo.x[0] << " %f\n", tree2.boxes[nb].lo.x[1]);
// System.out.printf(tree2.boxes[nb].hi.x[0] << " %f\n", tree2.boxes[nb].hi.x[1]);
localflag = localflag || (y.x[0] < tree2.boxes[nb].lo.x[0]);
localflag = localflag || (y.x[0] > tree2.boxes[nb].hi.x[0]);
localflag = localflag || (y.x[1] < tree2.boxes[nb].lo.x[1]);
localflag = localflag || (y.x[1] > tree2.boxes[nb].hi.x[1]);
globalflag = globalflag || localflag;
if (localflag) {
fail("*** KDtree<2>,locate(Point): The located box does not contain selected point");
}
}
// Test locate(int) method
int n0;
localflag=false;
for (i=0;i<M;i++) {
n0=myran.int32p() % N;
nb=tree2.locate(n0);
// System.out.printf(nb);
// System.out.printf(tree2.boxes[nb].lo.x[0] << " %f\n", tree2.boxes[nb].lo.x[1]);
// System.out.printf(tree2.boxes[nb].hi.x[0] << " %f\n", tree2.boxes[nb].hi.x[1]);
localflag = localflag || (kd2[n0].x[0] < tree2.boxes[nb].lo.x[0]);
localflag = localflag || (kd2[n0].x[0] > tree2.boxes[nb].hi.x[0]);
localflag = localflag || (kd2[n0].x[1] < tree2.boxes[nb].lo.x[1]);
localflag = localflag || (kd2[n0].x[1] > tree2.boxes[nb].hi.x[1]);
globalflag = globalflag || localflag;
if (localflag) {
fail("*** KDtree<2>,locate(int): The located box does not contain selected point");
}
}
// Test disti() method
int n1,n2;
sbeps=1.e-15;
localflag=false;
for (i=0;i<M;i++) {
n1=myran.int32p() % N;
n2=myran.int32p() % N;
double dis=tree2.disti(n1,n2);
// System.out.printf(dis << " %f\n", sqrt(SQR(kd2[n1].x[0]-kd2[n2].x[0])
// + SQR(kd2[n1].x[1]-kd2[n2].x[1])));
if (n1 == n2)
localflag = localflag || dis < 1.e99;
else
localflag = localflag || (dis-sqrt(SQR(kd2[n1].x[0]-kd2[n2].x[0])
+ SQR(kd2[n1].x[1]-kd2[n2].x[1]))) > sbeps;
globalflag = globalflag || localflag;
if (localflag) {
fail("*** KDtree<2>,disti(): The disti() method gave an incorrect result");
}
}
// Test nearest() method
int j,n3;
double dis2sq;
localflag=false;
for (i=0;i<M;i++) {
y.x[0]=myran.doub();
y.x[1]=myran.doub();
n3=tree2.nearest(y);
dis2sq=SQR(kd2[n3].x[0]-y.x[0])+SQR(kd2[n3].x[1]-y.x[1]);
for (j=0;j<N;j++) {
if (j != n3) localflag = localflag ||
(SQR(kd2[j].x[0]-y.x[0])+ SQR(kd2[j].x[1]-y.x[1])) < dis2sq;
}
globalflag = globalflag || localflag;
if (localflag) {
fail("*** KDtree<2>,nearest(): Exhaustive search found closer point");
}
}
// Test nnearest() method
int n4,n,nfar,K=5;
boolean test;
double far;
int[]nn=new int[K];
double[] dn=new double[K];
localflag=false;
for (i=0;i<M;i++) {
n4=myran.int32p()%N;
tree2.nnearest(n4,nn,dn,K); // Find K nearest Points
// See if there is anything closer than the furthest
// of these points, other than the other points in the list nn[]
far=0.0;
nfar=0;
for (j=0;j<K;j++)
if (dn[j] > far) {
far=dn[j];
nfar=nn[j];
}
test=false;
for (j=0;j<N;j++) {
for (n=0;n<K;n++)
test = test || (nn[n] == j);
if (!test)
localflag = localflag || (tree2.disti(j,n4) < far);
globalflag = globalflag || localflag;
if (localflag) {
fail("*** KDtree<2>,nnearest(): Found a nearer point than the supposed n nearest");
}
}
}
// Test locatenear() method
int nmax=N/10;
int[] list=new int[nmax];
double r=0.1;
y.x[0]=0.5;
y.x[1]=0.5;
int nret=tree2.locatenear(y,r,list,nmax);
// Check the result by brute force
int[] list2=new int[nmax];
int nret2=0;
for (i=0;i<N;i++) {
if ((dist(y,kd2[i]) < r) && (nret2 < nmax)) {
list2[nret2]=i;
nret2++;
}
}
// System.out.printf(nret << " %f\n", nret2);
localflag = (nret != nret2);
globalflag = globalflag || localflag;
if (localflag) {
fail("*** KDtree<2>,locatenear(): Found different number of points closer than radius r");
}
// Make sure list[] and list2[] are the same
int[] llist=buildVector(list),llist2=buildVector(list2);
Arrays.sort(llist);
Arrays.sort(llist2);
localflag=false;
for (i=0;i<nret;i++) {
// System.out.printf(llist[i] << " %f\n", llist2[i]);
localflag=localflag || (llist[i] != llist2[i]);
}
globalflag = globalflag || localflag;
if (localflag) {
fail("*** KDtree<2>,locatenear(): The list of nearby points is not correct");
}
// Repeat all the tests in 3D
// Test KDtree in 3D
for (i=0;i<N;i++) {
kd3[i] = new Point(3);
kd3[i].x[0]=myran.doub();
kd3[i].x[1]=myran.doub();
kd3[i].x[2]=myran.doub();
}
KDtree tree3 = new KDtree(3,kd3);
// Test locate(Point) method in 3D
Point yy=new Point(3);
localflag=false;
for (i=0;i<M;i++) {
yy.x[0]=myran.doub();
yy.x[1]=myran.doub();
yy.x[2]=myran.doub();