Least Squares Fit Sourcecode




This page lists the source for the applet that loads a file and generates a least squares fit to a line. Note that the code is far from being intended as an example of ‘quality’ programming practice. It based on a demo written in a hurry for the Wakefield Show. By all means write better programs than this! Use it to frighten your children! Note the stunning comments... or rather their total absence.

Note that the program contains some ‘fudges’ to get around some limits and ‘features’ of the current version of !Java. For that reason it should not be expected to run on non RiscOS machines. It also bears the scars of initially being written for a 1.1.5 JVM/JRE and then bodged for 1.0.2.


/* input from file */

import java.applet.*;
import java.awt.*;
import java.io.*;
import java.lang.*;


public class jlsq extends Applet{
  
  String relName;
  File fl = new File(" ");
  Font theFont = new Font("TimesRoman",Font.BOLD,20);
  Font smallFont = new Font("TimesRoman",Font.PLAIN,18);
  Font italicFont = new Font("TimesRoman",Font.ITALIC,18);
  FileInputStream from = null;
  byte[] buffer = new byte[4096];
  int bytes_read, count, i, ils, ixydiv, num_pairs, ip;
  int ytext;
  StringBuffer xsbuf = new StringBuffer(0);
  StringBuffer ysbuf = new StringBuffer(0);
  char ch;
  double x[] = new double[100];
  double y[] = new double[100];
  double xmax,ymax,xmin,ymin;
  double a,b,sumx,sumy,sumxy,sumx2;
  int redx0,redy0,redw,redh;
  
  
  public void init() {
    relName=getCodeBase().toString()+getParameter("datafile").toString();
    relName=fixup(relName);
    fl = new File(relName);
    get_file_input();
    analyse();
  }

  public void get_file_input() {
    if (fl.exists()) {
      System.out.print("file found");
    }
    else
    {
      System.out.print("the input file = "+relName+" not found");
    }
    count=0;
    try {
      from = new FileInputStream(fl);
      while ((bytes_read = from.read(buffer)) != -1)
      {
        count=bytes_read;
      }
    }
    catch (FileNotFoundException e) { ; }
    catch (IOException e) { ; }
    finally {
      if (from != null ) try { from.close(); } catch (IOException e) { ; }
    } 
    i=0; ip=0; ils=0; ytext=120;
    
      while ((char)buffer[i] != '*')
      {
      xsbuf.setLength(0);
      ysbuf.setLength(0);
      while ( (ch=(char)buffer[i]) != ',')
      {
        if (ch != ' ') xsbuf.append(ch);
        i=i+1;
      }
      i=i+1;
      ixydiv=i;
      while ( (ch=(char)buffer[i]) != '\n')
      {
        if (ch != ' ') ysbuf.append(ch);
        i=i+1;
      }
      ysbuf.append('\0');
      i=i+1;
      ip=ip+1; ils=i;
      try {  
        x[ip]=Double.valueOf(xsbuf.toString()).doubleValue();
      }
      catch (ParseException e) {
        x[ip]=-99.0;
      }
      try {
        y[ip]=Double.valueOf(ysbuf.toString()).doubleValue();
      }
      catch (ParseException e) {
        y[ip]=-99.0;
      }
    }
    num_pairs=ip;
  }
  
  public String fixup(String sin) {
    String sout;
    int slen,si;
    char chs;
    slen=sin.length();
    sout="";
    si=6;
    while (si<slen)
    {
      chs=sin.charAt(si);
      if (chs == '/' ) { chs='.'; }
      sout=sout+chs;
      si=si+1;
    }
    return sout;
  }

  public void analyse() {
    int iap;
    double fnp;
    iap=1;
    xmax=-9999.0;  xmin=9999.0;
    ymax=-9999.0;  ymin=9999.0;
    sumx=0.0;  sumy=0.0;  sumxy=0.0;  sumx2=0.0;
    while (iap <= num_pairs) {
      if ( x[iap] > xmax )  xmax=x[iap];
      if ( x[iap] < xmin )  xmin=x[iap];
      if ( y[iap] > ymax )  ymax=y[iap];
      if ( y[iap] < ymin )  ymin=y[iap];
      sumx=sumx+x[iap];
      sumy=sumy+y[iap];
      sumxy=sumxy+x[iap]*y[iap];
      sumx2=sumx2+x[iap]*x[iap];
      iap=iap+1;
    }
    fnp=(double)num_pairs;
    b=fnp*sumxy-sumx*sumy;
    a=fnp*sumx2-sumx*sumx;
    b=b/a;
    a=sumy-b*sumx;
    a=a/fnp;
  }

  public void paint(Graphics g) {
    g.setColor(new Color(0,0,0));
    g.setFont(theFont);
    if (fl.exists()) {
      g.drawString("bytes read = "+bytes_read,10,80);
      g.drawString("input file = "+relName,10,100);
      draw_graph(g);
    }
    else
    {
      g.drawString("file not found!", 50, 50);
      g.drawString("see javaout",50,70);
    }
  }
  
  public void draw_graph(Graphics gin) {
    int x0, y0, wide, high, igp, edge;
    int xp, yp, ye, xe;
    double xscale,yscale;
    StringBuffer osbuf = new StringBuffer(0);
    x0=20;  y0=20;  edge=10;
    wide=400;  high=300;
    gin.setColor(new Color(255,255,255));
    gin.fillRoundRect(1,1,539,399,20,20);
    gin.setColor(new Color(0,0,0));
    gin.drawRoundRect(1,1,539,399,20,20);
    gin.setColor(new Color(180,180,255));
    gin.fillRect(x0-edge,y0-edge,wide+2*edge,high+2*edge);
    gin.setColor(new Color(0,0,255));
    gin.drawRect(x0-edge,y0-edge,wide+2*edge,high+2*edge);
    xscale=(double)wide;
    xscale=xscale/(xmax-xmin);
    yscale=(double)high;
    yscale=yscale/(ymax-ymin);
    igp=1;
    while (igp <= num_pairs)
    {
      xp=(int)((x[igp]-xmin)*xscale);
      yp=(int)((y[igp]-ymin)*yscale);
      gin.drawOval(x0+xp-2,y0+high-yp-2,6,6);
      igp=igp+1;
    }
    xp=(int)((x[1]-xmin)*xscale);
    yp=(int)(((a+b*x[1])-ymin)*yscale);
    xe=(int)((x[num_pairs]-xmin)*xscale);
    ye=(int)(((a+b*x[num_pairs])-ymin)*yscale);
    gin.setColor(new Color(0,180,0));
    gin.drawLine(x0+xp,y0+high-yp,x0+xe,y0+high-ye);
    gin.drawLine(x0+xp+1,y0+high-yp,x0+xe+1,y0+high-ye);
    redx0=x0+wide+2*edge;  redy0=y0+high-redh; redw=90; redh=25;
    gin.setColor(new Color(220,255,80));
    gin.fillRoundRect(redx0,redy0,redw,redh,10,10);
    gin.setColor(new Color(0,0,0));
    gin.drawRoundRect(redx0,redy0,redw,redh,10,10);
    gin.drawString("Replot!",redx0+20,redy0+redh-8);
    gin.setColor(new Color(220,180,220));
    gin.fillRoundRect(redx0,y0-edge,redw,high-redh-16,10,10);
    gin.fillRoundRect(x0-edge,y0+high+24,wide+3*edge+redw,25,10,10);
    gin.setColor(new Color(0,0,0));
    gin.drawRoundRect(redx0,y0-edge,redw,high-redh-16,10,10);
    gin.drawRoundRect(x0-edge,y0+high+24,wide+3*edge+redw,25,10,10);
    gin.setFont(smallFont);
    gin.drawString("Fit to:",redx0+8,y0+8);
    gin.setFont(italicFont);
    gin.drawString("y = ax + b",redx0+8,y0+24);
    gin.drawString("a =",redx0+8,y0+50);
    gin.drawString("b =",redx0+8,y0+100);
    osbuf.append(String.valueOf(b));
    osbuf.setLength(  osbuf.toString().indexOf('.') + 5 );
    gin.setFont(smallFont);
    gin.drawString("  "+osbuf,redx0+8,y0+70);
    osbuf.setLength(0);
    osbuf.append(String.valueOf(a));
    osbuf.setLength(  osbuf.toString().indexOf('.') + 3 );
    gin.setFont(smallFont);
    gin.drawString("  "+osbuf,redx0+8,y0+120);
    gin.drawString("Input file = "+relName,x0,y0+high+42);
    gin.setFont(theFont);
    gin.drawString(num_pairs+ "  points",redx0+8,y0+200);
  }
  
  public boolean mouseDown(Event mev, int mx, int my) {
    if ( (mx>=redx0) && (mx<=(redx0+redw)) && (my>=redy0) && (my<=(redy0+redh)))
    {
      get_file_input();
      analyse();
      repaint();
    }
    return true;
  }
}



Content and pages maintained by: Jim Lesurf (jcgl@st-and.demon.co.uk)
using HTMLEdit and TW on a StrongARM powered RISCOS machine.