package org.mwg.experiments.kdtree;

import org.junit.Test;
import org.mwg.Callback;
import org.mwg.Graph;
import org.mwg.GraphBuilder;
import org.mwg.Node;
import org.mwg.core.scheduler.NoopScheduler;
import org.mwg.ml.MLPlugin;
import org.mwg.ml.common.distance.EuclideanDistance;
import org.mwg.ml.common.structure.KDNode;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Random;


/**
 * Created by assaad on 30/06/16.
 */
public class KDNodeTest {
    @Test
    public void KDInsertTest() {
        final Graph graph = new GraphBuilder()
                .withPlugin(new MLPlugin())
                .withScheduler(new NoopScheduler())
                .withMemorySize(100000)
                .withOffHeapMemory()
                .build();
        graph.connect(new Callback<Boolean>() {
            @Override
            public void on(Boolean result) {
                KDNode test= (KDNode) graph.newTypedNode(0,0,KDNode.NAME);
                test.set(KDNode.DISTANCE_THRESHOLD,1e-30);


                int dim=3;
                double[] vec=new double[dim];
                Random rand=new Random();
                int num=1000;
                graph.save(null);

                for(int i=0;i<num;i++){
                    double[] valuecop=new double[vec.length];
                    for(int j=0;j<dim;j++){
                        vec[j]=rand.nextDouble();
                        valuecop[j]=vec[j];
                    }

                    Node value= graph.newNode(0,0);
                    value.set("value",valuecop);

                    test.insert(vec,value,null);
                    value.free();
                    if(i%10000==0) {
                        graph.save(null);
                        System.out.println(i+", cache: "+graph.space().available()+", nodes: "+test.get(KDNode.NUM_NODES));
                    }
                }

                graph.save(null);
                System.out.println(num+", cache: "+graph.space().available()+", nodes: "+test.get(KDNode.NUM_NODES));

                double[] key=new double[dim];
                for(int i=0;i<dim;i++){
                    key[i]=0.1*(i+1);
                }

                NumberFormat formatter = new DecimalFormat("#0.0000");
                System.out.println();
                test.nearestN(key, 8, new Callback<Node[]>() {
                    @Override
                    public void on(Node[] result) {
                        for(int i=0;i<result.length;i++){
                            double[] vec=(double[]) result[i].get("value");
                            for(int j=0;j<vec.length;j++){
                                System.out.print(formatter.format(vec[j])+" ");
                            }
                            System.out.println("dist: " + formatter.format(new EuclideanDistance().measure(vec,key)));
                        }
                    }
                });
                graph.save(null);
                System.out.println("cache: "+graph.space().available());




            }
        });
    }
}
@@ -26,24 +26,53 @@
 ts.kdtree;%0A%0A
+import be.tarsos.lsh.Vector;%0A
 import org.j
@@ -404,32 +404,60 @@
 t.NumberFormat;%0A
+import java.util.ArrayList;%0A
 import java.util
@@ -759,16 +759,17 @@
 e(100000
+0
 )%0A      
@@ -1100,17 +1100,17 @@
 int dim=
-3
+4
 ;%0A      
@@ -1188,16 +1188,30 @@
  Random(
+1569358742365l
 );%0A     
@@ -1233,16 +1233,18 @@
 num=1000
+00
 ;%0A      
@@ -1271,16 +1271,127 @@
 (null);%0A
+                ArrayList%3Cdouble%5B%5D%3E vecs=new ArrayList%3Cdouble%5B%5D%3E();%0A%0A                long ts=System.nanoTime();
 %0A       
@@ -1636,32 +1636,67 @@
                %7D
+%0A                    vecs.add(vec);
 %0A%0A              
@@ -1885,16 +1885,18 @@
         
+/*
  if(i%2510
@@ -2084,32 +2084,34 @@
                %7D
+*/
 %0A               
@@ -2104,32 +2104,208 @@
                %7D
+%0A                long tf=System.nanoTime();%0A                double time=tf-ts;%0A                time=time/1000000;%0A                System.out.println(%22learning in %22+time+%22 ms%22);
 %0A%0A              
@@ -3440,16 +3440,960 @@
 ());%0A%0A%0A%0A
+                EuclideanDistance ed =new EuclideanDistance();%0A                double%5B%5D sum=new double%5B1%5D;%0A                sum%5B0%5D=0;%0A%0A                ts=System.nanoTime();%0A                for(int i=0;i%3Cvecs.size();i++)%7B%0A                    double%5B%5D v1=vecs.get(i);%0A                    test.nearestN(v1, 1, new Callback%3CNode%5B%5D%3E() %7B%0A                        @Override%0A                        public void on(Node%5B%5D result) %7B%0A                            for(int i=0;i%3Cresult.length;i++)%7B%0A                                double%5B%5D vect=(double%5B%5D) result%5Bi%5D.get(%22value%22);%0A                                double v3= ed.measure(v1,vect);%0A                                sum%5B0%5D+=v3;%0A                            %7D%0A                        %7D%0A                    %7D);%0A%0A%0A                %7D%0A                tf=System.nanoTime();%0A                time=tf-ts;%0A                time=time/1000000;%0A                System.out.println(%22Sum: %22+sum%5B0%5D+%22 in %22+time+%22 ms%22);%0A%0A
 %0A       

update test