/*
 * EigAccuracy.java
 *
 * Created on March 22, 2006, 5:24 PM
 */

package DDMT.Nodes;
import java.util.Vector;
import java.util.Random;
import java.io.*;

/**
 *
 * @author  Kanishka
 */
public class EigAccuracy 
{
    static int dimension = 15;
    static Vector DataPoints = new Vector();
    static DataGen dg = new DataGen(2);
    static int PercentPointstoReplace = 4;
    static int SIZE_OF_DATABASE = 200*50;
    static int Num_Centroids = 1;
    static int NumSamples = 4000;
    static Vector Times = new Vector();
    double[][] Matrix;
    
    
    public EigAccuracy() 
    {
        for (int i=0;i<this.SIZE_OF_DATABASE;i++)
        {
            dg.GenPoint(Num_Centroids, 0.1, 1);
            Point p = (Point)dg.GetPoint();
            this.DataPoints.add(p);
        }
        System.out.println(DataPoints.size());
    }
    
    public static void main(String[] args) 
    {
        Random r = new Random();
        int Ticks = 100000;
        EigAccuracy eigac = new EigAccuracy();
//        //un comment for cenentralized computations
        ReadEigTime("C:\\L2Synthetic\\Expts\\Eigen\\Samples\\1000\\EigenTime.txt");
        String ETick = (String)Times.elementAt(0);
        int ETime = Integer.parseInt(ETick);
        
        for (int i=0;i<Times.size();i++)
        {
            String t = (String)Times.elementAt(i);
            System.out.println(t);
        }
       
        for (int i=0;i<30*Ticks;i++)
        {
            
            if (i%1000==0)
                ReplaceData(i);
               
//            System.out.println(i+" "+KTime);
            if (i==ETime)
            {
                double[][] A = new double[dimension][dimension];
                System.out.println("Inside : "+i);
                Vector SampleVect = new Vector();
                
                //for the sampled centralized
//                for (int j=0;j<NumSamples;j++)
//                {
//                    int x = r.nextInt(DataPoints.size());
//                    SampleVect.add(DataPoints.elementAt(x));
//                }
//                
//                for (int k=0;k<NumSamples;k++)
//                {
//                    Point p = (Point)SampleVect.elementAt(k);
//                    int x = (int)p.x[0];
//                    int y = (int)p.x[1];
//                    if (dimension/2+x>=0&&x<dimension/2)
//                        if (dimension/2+y>=0&&y<dimension/2)
//                            A[dimension/2+x][dimension/2+y] += 1;
//                }
//
//                for (int m=0;m<dimension;m++)
//                    for (int n=0;n<dimension;n++)
//                        A[m][n]/=NumSamples;
//
//                PowerMethod pw = new PowerMethod(A,dimension,0.01,i);
//                System.out.println("Execution Complete");
//                double[] EigVec = new double[dimension];
//                EigVec = pw.retEigVec();
//                EigVec = SortEigVec(EigVec);
//                String CentroidString = MakeEigString(EigVec);
//                AppendFile("c:\\Eig.txt", ""+i+"\n");
//                AppendFile("c:\\Eig.txt", CentroidString+"\n\n");
//                AppendFile("c:\\EigVal.txt", WriteEigString(EigVec));
//                AppendFile("c:\\EigVal.txt", "\n");
                
                //for the whole dataset
                for (int m=0;m<dimension;m++)
                    for (int n=0;n<dimension;n++)
                        A[m][n] = 0.0;
                
                for (int k=0;k<SIZE_OF_DATABASE;k++)
                {
                    Point p = (Point)DataPoints.elementAt(k);
                    int x = (int)p.x[0];
                    int y = (int)p.x[1];
                    if (dimension/2+x>=0&&x<dimension/2)
                        if (dimension/2+y>=0&&y<dimension/2)
                            A[dimension/2+x][dimension/2+y] += 1;
                }

                for (int m=0;m<dimension;m++)
                    for (int n=0;n<dimension;n++)
                        A[m][n]/=SIZE_OF_DATABASE;

                PowerMethod pw = new PowerMethod(A,dimension,0.01,i);
                System.out.println("Execution Complete");
                double[] EigVec = new double[dimension];
                EigVec = pw.retEigVec();
                EigVec = SortEigVec(EigVec);
                String CentroidString = MakeEigString(EigVec);
                AppendFile("c:\\Eig.txt", ""+i+"\n");
                AppendFile("c:\\Eig.txt", CentroidString+"\n\n");
                AppendFile("c:\\EigVal.txt", WriteEigString(EigVec));
                AppendFile("c:\\EigVal.txt", "\n");
                
                Times.removeElementAt(0);
                if (Times.size()!=0)
                {
                    ETick = (String)Times.elementAt(0);
                    ETime = Integer.parseInt(ETick);
                }
                else
                    System.exit(0);
                
                while(ETime==i)
                {
                    AppendFile("c:\\Eig.txt", ""+i+"\n");
                    AppendFile("c:\\Eig.txt", CentroidString+"\n\n");
                    AppendFile("c:\\EigVal.txt", WriteEigString(EigVec));
                    AppendFile("c:\\EigVal.txt", "\n");
                    
                    Times.removeElementAt(0);
                    if (Times.size()!=0)
                    {
                        ETick = (String)Times.elementAt(0);
                        ETime = Integer.parseInt(ETick);
                    }
                    else
                        System.exit(0);
                }
            }
        }
    }
    

    public static void ReplaceData(int ClockTick)
    {
        int PointstoReplace = SIZE_OF_DATABASE*PercentPointstoReplace/100;
        for (int i=0;i<PointstoReplace;i++)
            DataPoints.removeElementAt(0);
        
        for (int i=0;i<PointstoReplace;i++)
        {
            dg.GenPoint(Num_Centroids, 0.1, ClockTick);
            Point p = (Point)dg.GetPoint();
            DataPoints.add(p);
        }
        
    }
    
    public static void AppendFile(String filename,String fileData) 
    {
        try 
        {
            BufferedWriter out = new BufferedWriter(new FileWriter(filename,true));
            out.write(fileData);
            out.close();
        }
        catch (IOException e) 
        {
            System.out.println("Writing exception");
        }
    }
    
    public static String MakeEigString(double[] EigVec)
    {
        String Msg = "EigenStates\n";
        for (int i=0;i<dimension;i++)
            Msg = Msg.concat(String.valueOf(EigVec[i])+"\n");
        Msg = Msg.concat("\n");
        //    System.out.println(Msg);
        return Msg;
    }
    
    public static String WriteEigString(double[] EigVec)
    {
        String Msg = "";
        for (int i=0;i<dimension;i++)
            Msg = Msg.concat(String.valueOf(EigVec[i])+"\n");
        //    System.out.println(Msg);
        return Msg;
    }
    
    /*
    public void CompareCentroids(String dFile, String sFile, String cFile, int dimension)
    {
        //dFile = distributed centroids, sFile = sampled centroids, cFile = actual centrids
        double[][] dCentroids = null;
        double[][] sCentroids = null;
        double[][] cCentroids = null;
        double[] distrComparison = null;
        double[] centrComparison = null;
        int numCentroids  = 0;
        //read dFile
        try
        {
            File file = new File(dFile);
            byte buffer[] = new byte[(int)file.length()];
            BufferedInputStream input = new BufferedInputStream(new FileInputStream(file));
            input.read(buffer,0,buffer.length);
            input.close();					 
            String fileData = new String(buffer);
            String[] centroids = fileData.split("\n");
            numCentroids = centroids.length;
            dCentroids = new double[numCentroids][dimension];
            for (int i=0;i<numCentroids;i++)
            {
                String[] elem = centroids[i].split(" ");
                for (int j=0;j<dimension;j++)
                    dCentroids[i][j] = Double.parseDouble(elem[j].trim());
            }
        }
        catch(IOException e)
        {
            System.out.println("File :"+dFile+" not found");
            System.exit(0);
        }
        
        //read sFile
        try
        {
            File file = new File(sFile);
            byte buffer[] = new byte[(int)file.length()];
            BufferedInputStream input = new BufferedInputStream(new FileInputStream(file));
            input.read(buffer,0,buffer.length);
            input.close();					 
            String fileData = new String(buffer);
            String[] centroids = fileData.split("\n");
            numCentroids = centroids.length;
            sCentroids = new double[numCentroids][dimension];
            for (int i=0;i<numCentroids;i++)
            {
                String[] elem = centroids[i].split(" ");
                for (int j=0;j<dimension;j++)
                    sCentroids[i][j] = Double.parseDouble(elem[j].trim());
            }
        }
        catch(IOException e)
        {
            
        }
        
        //read cFile
        try
        {
            File file = new File(cFile);
            byte buffer[] = new byte[(int)file.length()];
            BufferedInputStream input = new BufferedInputStream(new FileInputStream(file));
            input.read(buffer,0,buffer.length);
            input.close();					 
            String fileData = new String(buffer);
            String[] centroids = fileData.split("\n");
            numCentroids = centroids.length;
            cCentroids = new double[numCentroids][dimension];
            for (int i=0;i<numCentroids;i++)
            {
                String[] elem = centroids[i].split(" ");
                for (int j=0;j<dimension;j++)
                    cCentroids[i][j] = Double.parseDouble(elem[j].trim());
            }
        }
        catch(IOException e)
        {
            
        }
        
        System.out.println("File :"+dFile+" found");
        System.out.println("File :"+sFile+" found");
        System.out.println("File :"+cFile+" found");
        
        distrComparison = new double[numCentroids];
        centrComparison = new double[numCentroids];
        //actual comparison
        for (int i=0;i<numCentroids;i++)
        {
            distrComparison[i] = 0.0;
            for (int j=0;j<dimension;j++)
            {
                distrComparison[i]+=(dCentroids[i][j]-cCentroids[i][j])*(dCentroids[i][j]-cCentroids[i][j]);
                centrComparison[i]+=(sCentroids[i][j]-cCentroids[i][j])*(sCentroids[i][j]-cCentroids[i][j]);
            }
            distrComparison[i]=Math.sqrt(distrComparison[i]);
            centrComparison[i]=Math.sqrt(centrComparison[i]);
            System.out.println(distrComparison[i]+" "+centrComparison[i]);
        }
        
        Arrays.sort(distrComparison);
        Arrays.sort(centrComparison);
        
        double avgDistr = 0.0;
        double avgCentr = 0.0;
        
        for (int i=0;i<distrComparison.length;i++)
        {
            avgDistr +=distrComparison[i];
            avgCentr +=centrComparison[i];
        }
        avgDistr/=distrComparison.length;
        avgCentr/=centrComparison.length;
        System.out.println("\nDistributed:Overall\n"+"Max : "+distrComparison[distrComparison.length-1]+"\nMin : "+distrComparison[0]+"\nAvg : "+avgDistr+"\n\n");
        System.out.println("\nCentralized:Overall\n"+"Max : "+centrComparison[centrComparison.length-1]+"\nMin : "+centrComparison[0]+"\nAvg : "+avgCentr+"\n\n");
    }
     **/
    
    public static void ReadEigTime(String FileName)
    {
        try
        {
            File f = new File(FileName);
            
            FileReader fr = new FileReader(FileName);
            BufferedReader reader = new BufferedReader(fr);
           
            String lines = reader.readLine();
            Vector Temp = new Vector();	
            
            while(lines!=null)
            {
                Temp.add(lines);
                lines = reader.readLine(); 
            }
            
            while(Temp.size()!=0)
            {
                //add the time
                String t = (String)Temp.elementAt(0);
                String tt = new String(t);
                Times.add(tt);
                Temp.removeElementAt(0);
                Temp.removeElementAt(0);
                
                String Filename = "C:\\L2Synthetic\\Expts\\Eigen\\Samples\\1000\\EigenVectors.txt";
                //output the eigenvector
                for (int i=0;i<dimension;i++)
                {
//                    AppendFile(Filename, (String)Temp.elementAt(0)+"\n");
                    Temp.removeElementAt(0);
                }
//                AppendFile(Filename, "\n");
                
                Temp.removeElementAt(0);
                Temp.removeElementAt(0);
                Temp.removeElementAt(0);
                Temp.removeElementAt(0);
                Temp.removeElementAt(0);
            }
        }
        catch(IOException e)
        {
            
        }
    }
    
    public static double[] SortEigVec(double[] EigVec)
    {
     //   AppendFile("c:\\Tempori.txt",this.MakeString(Data));
        // sort by x
        for (int i=0;i<dimension;i++)
        {
            int min = i;
            for (int j=i+1;j<dimension;j++)
            {
                if (EigVec[i]<EigVec[min])
                {
                    min = j;
                }
            }
            if (min!=i)
            {
             //   Point t = (Point)Data.elementAt(i);
            //    System.out.println(t.x+" -");
                //swap min and i
                double temp = EigVec[i];
                EigVec[i] = EigVec[min];
                EigVec[min] = temp;
            }
        }
     //   AppendFile("c:\\Tempnew.txt",this.MakeString(Data));
    //    System.exit(0);
        return EigVec;
    }
    
}
