// Newton's Method, coded by David Protas, c.2002
// Any corrections or suggestions for improvement of this code will be appreciated
// and should be sent to david.protas@csun.edu 

import java.applet.*;
import java.awt.*;

public class NnM extends Applet
{
   final int N = 400;  //number of sample points used to draw graph
   
   double[] xarray = new double[N+1];
   double[] yarray = new double[N+1];
   double aD, bD, a5D, a4D, a3D, a2D, a1D, a0D, ymin, ymax, rD, next_rD;
   int counter = 0;
   Panel top, middle, bottom, pan1, pan2, pan3, pan4, pan5;
   Label enterCoeffs;
   Label polynomial;
   Label x5, x4, x3, x2, x1;
   Label enterEndPts;
   Label leftEndPt, rightEndPt;
   Label message, message2;
   Label enterStartPt, startPt;
   TextField a5, a4, a3, a2, a1, a0;
   TextField a, b;
   TextField r1;
   TextArea results;
   Button plot;
   Button calculate;
   GCanvas graph;
   Color babyBlue;
   
   public void init()
   {
      setLayout(new BorderLayout(4,0));
      top = new Panel();
      top.setLayout(new GridLayout(5,1));
      bottom = new Panel();
      bottom.setLayout(new GridLayout(2,1));
      pan1 = new Panel();
      pan2 = new Panel();
      pan3 = new Panel();
      pan3.setLayout(new FlowLayout(FlowLayout.LEFT));
      middle = new Panel();
      pan4 = new Panel();
      pan5 = new Panel();
      enterCoeffs = new Label("Enter the coefficients: ");
      polynomial = new Label("p(x) =");
      x5 = new Label("x^5 +");
      x4 = new Label("x^4 +");
      x3 = new Label("x^3 +");
      x2 = new Label("x^2 +");
      x1 = new Label("x +");
      enterEndPts = new Label("Enter the endpoints:");
      leftEndPt = new Label("  a =");
      rightEndPt = new Label("  b =");
      message = new Label("                                                       ");
      message2 = new Label("                                                              ");
      enterStartPt = new Label("Enter the starting approximation:  ");
      startPt = new Label("  x_1 =");
      a5 = new TextField(3);
      a4 = new TextField(3);
      a3 = new TextField(3);
      a2 = new TextField(3);
      a1 = new TextField(3);
      a0 = new TextField(3);
      a = new TextField(3);
      b = new TextField(3);
      r1 = new TextField(3);
      results = new TextArea("    x_n            p(x_n) ", 10, 30);
      results.setEditable(false);
      plot = new Button("Plot");
      calculate = new Button("Newton step");
      graph = new GCanvas();
      babyBlue = new Color(204,255,255);
      
      top.add(enterCoeffs);
      pan1.add(polynomial);
      pan1.add(a5);
      pan1.add(x5);
      pan1.add(a4);
      pan1.add(x4);
      pan1.add(a3);
      pan1.add(x3);
      pan1.add(a2);
      pan1.add(x2);
      pan1.add(a1);
      pan1.add(x1);
      pan1.add(a0);
      top.add(pan1);
      top.add(enterEndPts);
      pan2.add(leftEndPt);
      pan2.add(a);
      pan2.add(rightEndPt);
      pan2.add(b);
      top.add(pan2);
      pan3.add(plot);
      pan3.add(message);
      top.add(pan3);
      add("North",top);
      add("Center",graph);
      add("East",results);
      pan4.add(enterStartPt);
      pan4.add(startPt);
      pan4.add(r1);
      bottom.add(pan4);
      pan5.add(calculate);
      pan5.add(message2);
      bottom.add(pan5);
      add("South",bottom);
      
      setBackground(babyBlue);
      enterCoeffs.setBackground(babyBlue);
      pan1.setBackground(babyBlue);
      enterEndPts.setBackground(babyBlue);
      pan2.setBackground(babyBlue);
      pan3.setBackground(babyBlue);
      message.setForeground(Color.red);
      message.setBackground(babyBlue);
      results.setFont(new Font("Courier",Font.PLAIN,10));
      polynomial.setBackground(babyBlue);
      x5.setBackground(babyBlue);
      x4.setBackground(babyBlue);
      x3.setBackground(babyBlue);
      x2.setBackground(babyBlue);
      x1.setBackground(babyBlue);
      r1.setBackground(babyBlue);
      leftEndPt.setBackground(babyBlue);
      rightEndPt.setBackground(babyBlue);
      enterStartPt.setBackground(babyBlue);
      startPt.setBackground(babyBlue);
      pan4.setBackground(babyBlue);
      message2.setForeground(Color.red);
      message2.setBackground(babyBlue);
      pan5.setBackground(babyBlue);
   }
   
   public boolean action(Event evt, Object arg)
   {
      if (evt.target == plot)
      {
         String a5S, a4S, a3S, a2S, a1S, a0S, aS, bS;

         results.setText("    x_n            p(x_n) ");
         a5S = a5.getText();
         a4S = a4.getText();
         a3S = a3.getText();
         a2S = a2.getText();
         a1S = a1.getText();
         a0S = a0.getText();
         aS = a.getText();
         bS = b.getText();
         if (entryValid(a5S) && entryValid(a4S) && entryValid(a3S) && entryValid(a2S) &&
             entryValid(a1S) && entryValid(a0S) && entryValid(aS) && entryValid(bS)) { 
            a5D = doubleFromString(a5S);
            a4D = doubleFromString(a4S);
            a3D = doubleFromString(a3S);
            a2D = doubleFromString(a2S);
            a1D = doubleFromString(a1S);
            a0D = doubleFromString(a0S);
            aD = doubleFromString(aS);
            bD = doubleFromString(bS);
            message.setText("");
            if (aD >= bD)
               message.setText("Need a < b.  Enter endpoints again.");
            else {
               graph.aD = aD;
               graph.bD = bD;
               ymin = p(aD,a5D,a4D,a3D,a2D,a1D,a0D);
               ymax = p(aD,a5D,a4D,a3D,a2D,a1D,a0D);
               for (int i = 0; i <= N; i++) {
                  xarray[i] = aD + i*(bD - aD)/N;                    //array of x values
                  yarray[i] = p(xarray[i],a5D,a4D,a3D,a2D,a1D,a0D);  //array of y values
                  graph.xarray[i] = xarray[i];
                  graph.yarray[i] = yarray[i];
                  if (yarray[i] < ymin)
                     ymin = yarray[i];          //find min value of y
                  if (yarray[i] > ymax)
                     ymax = yarray[i];          //find max value of y
               }
                  graph.ymin = ymin;
                  graph.ymax = ymax;
               if (ymin*ymax > 0)
                  message.setText("No root in interval.  Try again.");
               else if (ymin == ymax)
                  message.setText("Function is constant.  Try again.");
               else {
                  counter = 0;
                  graph.counter = counter;
                  graph.repaint();
                  counter = counter + 1;
               }      
            }   //end of else
         }   //end of if entryValid
         else
            message.setText("Invalid entry.  Try again.");    
         return true;
      }    //end of if evt.target plot
      
      if (evt.target == calculate)
      {
         String rS;
         
         message2.setText("");
         if (counter == 1) {
            rS = r1.getText();
            if (entryValid(rS)) {
               rD = doubleFromString(rS);
               if ((rD < aD) || (rD > bD))
                  message2.setText("Need a < x_1 < b.  Try again.");
               else if (deriv(rD,a5D,a4D,a3D,a2D,a1D,a0D) == 0)
                  message2.setText("p'(x_1) = 0.  Choose new x_1.");
               else {
                  graph.rD = rD;
                  results.appendText("\n"+rndOff(rD)+"  "+
                                     rndOff(p(rD,a5D,a4D,a3D,a2D,a1D,a0D)));
                  next_rD = rD - p(rD,a5D,a4D,a3D,a2D,a1D,a0D)/deriv(rD,a5D,a4D,a3D,a2D,a1D,a0D);
                  results.appendText("\n"+rndOff(next_rD)+"  "+
                                     rndOff(p(next_rD,a5D,a4D,a3D,a2D,a1D,a0D)));
                  graph.next_rD = next_rD;
                  graph.counter = counter;
                  graph.repaint(); 
                  counter = counter + 1;
               }   //end of else
            }    //end of if entryValid
            else
               message2.setText("Invalid entry.  Try again.");
         }   //end of if counter = 1
         else {
            rD = next_rD;
            if ((rD > 999.9) || (rD < -999.9))
               message2.setText("|x_n| too large.  Choose new x_1.");
            else if (deriv(rD,a5D,a4D,a3D,a2D,a1D,a0D) == 0)
               message2.setText("p'(x_n) = 0.  Choose new x_1.");
            else {
               graph.rD = rD;
               next_rD = rD - p(rD,a5D,a4D,a3D,a2D,a1D,a0D)/deriv(rD,a5D,a4D,a3D,a2D,a1D,a0D);
               results.appendText("\n"+rndOff(next_rD)+"  "+
                                     rndOff(p(next_rD,a5D,a4D,a3D,a2D,a1D,a0D)));
               graph.next_rD = next_rD;
               counter = counter + 1;
               graph.counter = counter;
               graph.repaint();
            }   //end of else
         }   //end of else counter
         return true;
      }    //end of if evt.target calculate
      return false;
   }   //end of action

   private double p(double t,double a5D,double a4D,double a3D,
                    double a2D,double a1D,double a0D)
   { 
      return ((((a5D*t+a4D)*t+a3D)*t+a2D)*t+a1D)*t+a0D;
   }
   
   private double deriv(double t,double a5D,double a4D,double a3D,
                        double a2D,double a1D,double a0D)
   { 
      return (((5*a5D*t+4*a4D)*t+3*a3D)*t+2*a2D)*t+a1D;
   }
   
   public static double doubleFromString(String str)
   { 
      Double doubleObj = new Double(str); 
      return doubleObj.doubleValue(); 
   }
 
   public static String rndOff(double number)  //to 8 places past the decimal
   {
      String strnum, bigstrnum, substrnum = "   0.00000000";
      double rndnum;
      int period, lngth;
      long longnum;
      
      if ((number >= 0.001) || (number <= -0.001)) {
         rndnum = Math.pow(0.1,8)*Math.round(Math.pow(10,8)*number);
         if (rndnum == 0)
            strnum = "0.00000000";
         else
            strnum = String.valueOf(rndnum);
         bigstrnum = "    " + strnum + "00000000";
         period = bigstrnum.indexOf('.');
         substrnum = bigstrnum.substring(period -4, period + 9);
         if ((rndnum >= 10000) || (rndnum <= -1000))
            substrnum = "big magnitude";
      }
      else {
         longnum = Math.round(Math.pow(10,8)*number);
         if (longnum == 0)
            substrnum = "   0.00000000";
         else {
            strnum = String.valueOf(longnum);
            if (longnum < 0)
               strnum = strnum.substring(1);
            lngth = strnum.length();
            switch (lngth) {
               case 1:
                  substrnum = "   0.0000000" + strnum;
                  break;
               case 2:
                  substrnum = "   0.000000" + strnum;
                  break;
               case 3:
                  substrnum = "   0.00000" + strnum;
                  break;
               case 4:
                  substrnum = "   0.0000" + strnum;
                  break;
               case 5:
                  substrnum = "   0.000" + strnum;
                  break;
               default:
                  substrnum = "   error";
            }
            if (longnum < 0)
               substrnum = "  -" + substrnum.substring(3);
         }
      }
      return substrnum;
   }
      
   private boolean entryValid(String entry)
   {
      boolean status;
       
      try {
         double number = doubleFromString(entry);
         status = true;
      }
      catch(NumberFormatException e) {
         status = false;
      }
      return status;
   }
   
}    //end of NnM

/*****************************************************************************/

import java.awt.*;

public class GCanvas extends Canvas
{      
   final int N = 400;  //number of steps used to draw graph
   
   Dimension d;   
   double[] xarray = new double[N+1];
   double[] yarray = new double[N+1];
   double aD, bD, ymin, ymax, rD, next_rD;
   int counter, tick;
   
   public void paint(Graphics g) 
   {
      if (counter == 0) {
         d = this.size();
         g.setColor(new Color(204, 255, 255));      //babyBlue
         g.fillRect(0,0,d.width,d.height);      //clears the graph
         g.setColor(Color.black);
         if (ymin*ymin+ymax*ymax > 0)
            g.drawLine(0, yScaler(0.0), d.width, yScaler(0.0));   //x-axis
         if (aD*bD < 0)
            g.drawLine(xScaler(0.0), 0, xScaler(0.0), d.height - 6);  //y-axis
         tick = (int)aD;    // start of x-ticks
         do {
            if (tick != 0) {
               g.drawString(tick+"", xScaler(tick) - 3, yScaler(0.0) + 11);
               g.drawLine(xScaler(tick), yScaler(0.0) - 2, xScaler(tick), yScaler(0.0));
            }
            tick = tick + 1;
         }
         while (tick <= bD);  //end of x-ticks
         for (int j = 0; j < N; j++) {
            g.drawLine(xScaler(xarray[j]),yScaler(yarray[j]), 
                                  xScaler(xarray[j+1]),yScaler(yarray[j+1]));
         }
      }
      else {
         g.setColor(Color.lightGray);
         g.drawLine(xScaler(rD), yScaler(0.0), xScaler(rD),
                    yScaler(yarray[(int)(N*(rD - aD)/(bD - aD))]));
         g.setColor(Color.red);
         g.drawLine(xScaler(rD), yScaler(yarray[(int)(N*(rD - aD)/(bD - aD))]), 
                    xScaler(next_rD), yScaler(0.0));
      }
   }

   public void update(Graphics g)     // now, repaint() won't first clear unless
   {                                  // clearing is put into paint(g)
      paint(g);
   }

   private int xScaler(double x)
   {  
      return (int)(5 + (d.width - 10)*(x - aD)/(bD - aD));
   }
   
   private int yScaler(double y)
   {
      return (int)((d.height - 11)*(1+(y - ymin)/(ymin - ymax)));
   } 
      
}


Back to applet