//======================================================
// Numerical Analysis package in java
// LeastApplet class for least square data analysis
// Dr. Turhan Coban
// =====================================================
import java.io.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
//import PlotShapes;
//import Numeric;
//import Text;

public class LeastApplet extends Applet implements ActionListener
{
  String label;                           // Plot Label
  String xlabel;                          // X axis Label
  String ylabel;                          // Y axis Label
  String filename;                        // file name
  double xmax,xmin,ymax,ymin;             // real max,min scale
  int xabsmin,yabsmin,abswidth,absheight; // absolute max,min scale
  int nmax;                               // max number of data points
  int nline;                              // max number of data sets
  double x[][];                           // x data
  double y[][];                           // y=f(x) data
  double ecof[]=new double[30];              // least square curve fitting  coeff.
  int n[];                                // n : number of data in each line
  int red[],green[],blue[];                // color code 0-255
  int plottype[];
  int xgridon;
  int ygridon;
  double xminout;
  double xmaxout;
  double nout;
  // plottype = 0 continuous line
  // plottype = 10 user defined character plot
  // plottype = 20 rectangle
  // plottype = 21 circle
  // plottype = 22 triangle
  // plottype = 23 diamond
  // plottype = 24 pentagon
  // plottype = 25 hexagon
  char ch[];    // plot character (used with plottype 10)
  int xntic;    // number of tics in x axis
  int yntic;    // number of tics in y axis
  Label promptXmin; // Label prompt in Xmin field
  Label promptXmax; // Label prompt in Xmax field
  Label promptYmin; // Label prompt in Ymin field
  Label promptYmax; // Label prompt in Ymax field
  Label promptInputFile;
  Label promptOutputFile;
  Label promptDegreeLSCF;
  TextField inputXmin;  // input field Xmin
  TextField inputXmax;  // input field Xmax
  TextField inputYmin;  // input field Ymin
  TextField inputYmax;  // input field Ymax
  TextField inputInputFile;
  TextField inputOutputFile;
  TextField inputDegreeLSCF;
  String fn[];
  int DegreeLSCF=4;


  public void set_plotwindow(double xip,double yip,double dxp,double dyp)
  {
    //sets rectangular plot window
    int w=getSize().width;
    int h=getSize().height;
    xabsmin   =  (int)(w*(xip+0.04));
    yabsmin   =  (int)(h*(yip+0.2));
    abswidth  =  (int)(w*dxp);
    absheight =  (int)(h*dyp);
  }


  public void init()
  {
  try {initplot();} catch(IOException e_eof) {showStatus("IO exception");}
  }

  public void initplot() throws IOException
  {
    //adding max-min prompts and input fields
    promptInputFile=new Label("Input File Name : ");
    add(promptInputFile);
    inputInputFile=new TextField(20);
    add(inputInputFile);
    inputInputFile.addActionListener(this);
    promptOutputFile=new Label("Output File Name : ");
    add(promptOutputFile);
    inputOutputFile=new TextField(20);
    add(inputOutputFile);
    inputOutputFile.addActionListener(this);
    promptDegreeLSCF=new Label("Degree of Least Square Curve Fittong : ");
    add(promptDegreeLSCF);
    inputDegreeLSCF=new TextField(5);
    add(inputDegreeLSCF);
    inputDegreeLSCF.addActionListener(this);
    promptXmin=new Label("Xmin ");
    add(promptXmin);
    inputXmin=new TextField(5);
    add(inputXmin);
    promptXmax=new Label("Xmax ");
    add(promptXmax);
    inputXmin.addActionListener(this);
    inputXmax=new TextField(5);
    add(inputXmax);
    promptYmin=new Label("Ymin ");
    add(promptYmin);
    inputXmax.addActionListener(this);
    inputYmin=new TextField(5);
    add(inputYmin);
    inputYmin.addActionListener(this);
    promptYmax=new Label("Ymax ");
    add(promptYmax);
    inputYmax=new TextField(5);
    add(inputYmax);
    inputYmax.addActionListener(this);
    //initial values of max and mins
    xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;
    label="Least Square Curve Fitting";
    xlabel="x";
    ylabel="y";
    nline=2;
    xntic=10;
    yntic=10;
    xgridon=1;
    ygridon=1;
    n=new int[2];
    red=new int[30];
    green=new int[30];
    blue=new int[30];
    plottype=new int[30];
    ch=new char[30];
    red[0]=0;
    green[0]=0;
    blue[0]=0;
    red[1]=0;
    green[1]=0;
    blue[1]=0;
    fn[0]="a.dat";
    plottype[0]=22;
    plottype[1]=0;
    fn[1]="b.dat";
    //read all data to determine limit values
    fn=new String[nline];
    int i,j;
    for(i=0;i<nline;i++)
    {
       j=0;
       n[i]=0;
       DataInputStream ffile=new DataInputStream(new FileInputStream(fn[i]));
       try{
       while(ffile!=null)
       {
       xtemp=Text.readDouble(ffile);
       ytemp=Text.readDouble(ffile);
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[i]++;
       }
          } catch(EOFException e_eof) {ffile.close();showStatus("end of file");}
       if(i==0) nmax=n[i];
       else
         {
         if(n[i]>nmax) nmax=n[i];
         }
    }
    x=new double[nline][nmax];
    y=new double[nline][nmax];
    //re-read the data again to load it
    for(i=0;i<nline;i++)
    {
       DataInputStream ffile=new DataInputStream(new FileInputStream(fn[i]));
       for(j=0;j<n[i];j++)
       {
          x[i][j]=Text.readDouble(ffile);
          y[i][j]=Text.readDouble(ffile);

       }
       ffile.close();
    }

    set_plotwindow(0.1,0.1,0.8,0.6);
  }

  public void paint(Graphics g)
  {
    inputInputFile.setText(fn[0]);
    inputOutputFile.setText(fn[1]);
    inputDegreeLSCF.setText(Integer.toString(DegreeLSCF));
    inputXmin.setText(Double.toString(xmin));
    inputXmax.setText(Double.toString(xmax));
    inputYmin.setText(Double.toString(ymin));
    inputYmax.setText(Double.toString(ymax));
    PlotShapes ps=new PlotShapes(g,xabsmin,yabsmin,absheight,abswidth,xmin,xmax,ymin,ymax);
    g.drawRect(xabsmin,yabsmin,abswidth,absheight);
    ps.drawXTic(xntic,(ymax-ymin)/80.0,0);
    ps.drawYTic(yntic,(xmax-xmin)/80.0,0);
    ps.drawXNumbers(xntic);
    ps.drawYNumbers(xntic);
    ps.drawLabel(label);
    ps.drawXLabel(xlabel);
    ps.drawYLabel(ylabel);
    if(xgridon!=0)
      ps.drawXGrid(xntic);
    if(ygridon!=0)
      ps.drawYGrid(yntic);
    int i,j;
    for(i=0;i<nline;i++)
    {
//  Select plot colors
    g.setColor(new Color(red[i],green[i],blue[i]));
    ps.drawPlotLines(i,plottype,x,y,n,ch);
      }//end of for(i=0
    }//end of method
public void InputDegreeLSCF() throws IOException
{
  DegreeLSCF=Integer.parseInt(inputDegreeLSCF.getText());
  ecof=Numeric.poly_least_square(x[0],y[0],DegreeLSCF);
  DataInputStream cin=new DataInputStream(System.in);
  PrintStream fout=new PrintStream(new FileOutputStream(fn[1]));
  System.out.println("minimum x : ");
  xminout=Text.readDouble(cin);
  System.out.println("maximum x : ");
  xmaxout=Text.readDouble(cin);
  System.out.println("number of data points : ");
  nout=Text.readInt(cin);
  double xxx;
  for(int i=0;i<nout;i++)
  {
    xxx=xminout+(xmaxout-xminout)/(nout-1)*i;
    fout.println(" "+x+" "+Numeric.f_least_square(ecof,xxx));
  }
  init();
  repaint();
}

public void InputFileRead() throws IOException
{
fn[1]=inputInputFile.getText();
  ecof=Numeric.poly_least_square(x[0],y[0],DegreeLSCF);
  DataInputStream cin=new DataInputStream(System.in);
  PrintStream fout=new PrintStream(new FileOutputStream(fn[1]));
  System.out.println("minimum x : ");
  xminout=Text.readDouble(cin);
  System.out.println("maximum x : ");
  xmaxout=Text.readDouble(cin);
  System.out.println("number of data points : ");
  nout=Text.readInt(cin);
  double xxx;
  for(int i=0;i<nout;i++)
  {
    xxx=xminout+(xmaxout-xminout)/(nout-1)*i;
    fout.println(" "+x+" "+Numeric.f_least_square(ecof,xxx));
  }
  init();
  repaint();
} //end of input file read

public void actionPerformed(ActionEvent e)
{
  fn[0]=inputInputFile.getText();
  init();
  try{InputFileRead();}catch(IOException ioe) {showStatus("IO exception");}
  try{InputDegreeLSCF();}catch(IOException ioe) {showStatus("IO exception");}
  Double valXmin=new Double(inputXmin.getText());
  xmin=valXmin.doubleValue();
  Double valXmax=new Double(inputXmax.getText());
  xmax=valXmax.doubleValue();
  Double valYmin=new Double(inputYmin.getText());
  ymin=valYmin.doubleValue();
  Double valYmax=new Double(inputYmax.getText());
  ymax=valYmax.doubleValue();
}

}



