// Euler's Method for Systems, coded by David Protas, c.2003 // Any corrections or suggestions for improvement of this code will be // appreciated and should be sent to david.protas@csun.edu // Latest revision: November 26, 2003 /********************* * Document: EuM.java *********************/ import java.applet.*; import java.awt.*; import expr.*; public class SysEu extends Applet { final int MaxN = 1000; //Maximum number of subintervals double t_0D, x_0D, y_0D, bD, xmin, xmax, ymin, ymax, h; int nI, counter = -1, last; double[] tArray = new double[MaxN+1]; double[] xArray = new double[MaxN+1]; double[] yArray = new double[MaxN+1]; double[] fArray = new double[MaxN+1]; double[] gArray = new double[MaxN+1]; Panel top, pan1, pan2, pan3, bottom, pan4, pan5; Label fLabel, gLabel, inputLabelX ,inputLabelY, inputLabelB, inputLabelN, message; TextField fField, gField, inputFieldX, inputFieldY, inputFieldB, inputFieldN; TextArea results; Button enter, approx; SysEu_G graph; Color babyBlue; public void init() { setLayout(new BorderLayout(4,0)); top = new Panel(); top.setLayout(new GridLayout(3,1)); bottom = new Panel(); bottom.setLayout(new GridLayout(3,1)); pan1 = new Panel(); pan2 = new Panel(); pan3 = new Panel(); pan4 = new Panel(); pan5 = new Panel(); fLabel = new Label("f(t,x,y) = "); gLabel = new Label("g(t,x,y) = "); fField = new TextField(20); gField = new TextField(20); inputLabelX = new Label(" x_0 ="); inputLabelY = new Label(" y_0 ="); inputLabelB = new Label(" b ="); inputLabelN = new Label(" n ="); inputFieldX = new TextField(5); inputFieldY = new TextField(5); inputFieldB = new TextField(5); inputFieldN = new TextField(5); enter = new Button("Enter"); approx = new Button("Approximate"); results = new TextArea(" t_n x_n y_n ", 10, 40); results.setEditable(false); message = new Label(" " + " "); graph = new SysEu_G(); babyBlue = new Color(204,255,255); pan1.add(fLabel); pan1.add(fField); pan1.add(gLabel); pan1.add(gField); top.add(pan1); pan2.add(inputLabelX); pan2.add(inputFieldX); pan2.add(inputLabelY); pan2.add(inputFieldY); top.add(pan2); pan3.add(inputLabelB); pan3.add(inputFieldB); pan3.add(inputLabelN); pan3.add(inputFieldN); pan3.add(enter); pan3.add(approx); top.add(pan3); add("North",top); add("Center",graph); add("East",results); pan5.add(message); bottom.add(pan5); add("South",bottom); setBackground(babyBlue); pan1.setBackground(babyBlue); pan2.setBackground(babyBlue); pan3.setBackground(babyBlue); pan4.setBackground(babyBlue); pan5.setBackground(babyBlue); message.setForeground(Color.red); message.setBackground(babyBlue); results.setFont(new Font("Courier",Font.PLAIN,10)); } public boolean action(Event evt, Object arg) { Variable t = null; Variable x = null; Variable y = null; Expr f = null, g = null, inputX = null, inputY = null, inputB = null; if (evt.target == enter) { counter = 0; graph.counter = counter; message.setText(""); try { t = Variable.make ("t"); x = Variable.make ("x"); y = Variable.make ("y"); f = Parser.parse (fField.getText()); g = Parser.parse (gField.getText()); inputX = Parser.parse(inputFieldX.getText()); inputY = Parser.parse(inputFieldY.getText()); inputB = Parser.parse(inputFieldB.getText()); } catch (Syntax_error e) { message.setText("" + e); } Variable.make ("pi").set_value (Math.PI); Variable.make ("e").set_value (Math.E); x_0D = inputX.value(); y_0D = inputY.value(); bD = inputB.value(); if (entryValid(inputFieldN.getText()) == false) message.setText("n needs to be an integer. Try again."); else { nI = intFromString(inputFieldN.getText()); last = nI; if((nI < 1) || (nI > MaxN)) message.setText("Applet requires n to be a positive integer <= " + MaxN); else if (bD > 0) { h = bD/nI; graph.h = h; graph.nI = nI; if (nI > 10) approx.setLabel("Run"); else approx.setLabel("Step"); results.setText(" t_n x_n y_n " + "\n" + rndOff(0) + " " + rndOff(x_0D) + " " + rndOff(y_0D)); graph.x_0D = x_0D; graph.y_0D = y_0D; graph.bD = bD; tArray[0] = 0; xArray[0] = x_0D; yArray[0] = y_0D; graph.tArray[0] = tArray[0]; graph.xArray[0] = xArray[0]; graph.yArray[0] = yArray[0]; xmin = Math.min(x_0D,-.5); xmax = Math.max(x_0D,.2); ymin = Math.min(y_0D,-.5); ymax = Math.max(y_0D,.2); for (int i = 1; i <= nI; i++) { t.set_value(tArray[i-1]); x.set_value(xArray[i-1]); y.set_value(yArray[i-1]); fArray[i-1] = f.value(); //Array of slopes gArray[i-1] = g.value(); //Array of slopes if (fArray[i-1] != fArray[i-1]) { //tests whether fArray[i-1] is a number message.setText("x'(" + rndOff(tArray[i-1]).trim() + ") is undefined. Computation ends there."); last = i-1; break; } if (gArray[i-1] != gArray[i-1]) { //tests whether gArray[i-1] is a number message.setText("y'(" + rndOff(tArray[i-1]).trim() + ") is undefined. Computation ends there."); last = i-1; break; } xArray[i] = xArray[i-1] + h*fArray[i-1]; //Array of x values yArray[i] = yArray[i-1] + h*gArray[i-1]; //Array of y values tArray[i] = i*h; //Array of t values if (xArray[i] < xmin) xmin = xArray[i]; //find min value of x if (xArray[i] > xmax) xmax = xArray[i]; //find max value of x 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.xmin = xmin; graph.xmax = xmax; graph.ymin = ymin; graph.ymax = ymax; graph.repaint(); } //end of else if bD > 0 else message.setText("Need b > 0. Try again."); } //end of else entry valid return true; } //end of evt.target == enter if (evt.target == approx) { if (nI > 10) { graph.counter = last; for (int i = 1; i <= last; i++) { graph.tArray[i] = tArray[i]; graph.xArray[i] = xArray[i]; graph.yArray[i] = yArray[i]; results.appendText("\n" + rndOff(tArray[i]) + " " + rndOff(xArray[i]) + " " + rndOff(yArray[i])); } graph.repaint(); } else { if (counter < last) { graph.nI = last; counter = counter + 1; results.appendText("\n" + rndOff(tArray[counter]) + " " + rndOff(xArray[counter]) + " " + rndOff(yArray[counter])); graph.counter = counter; for (int i = 1; i <= counter; i++) { graph.tArray[i] = tArray[i]; graph.xArray[i] = xArray[i]; graph.yArray[i] = yArray[i]; } graph.repaint(); } } return true; } //end of evt.target == approx return false; } //end of action public static int intFromString(String str) { Integer intObj = new Integer(str); return intObj.intValue(); } private boolean entryValid(String entry) { boolean status; try { double number = intFromString(entry); status = true; } catch(NumberFormatException e) { status =false; } return status; } public static String rndOff(double number) //to 5 places past the decimal { String strnum, bigstrnum, substrnum = " 0.00000"; int period, lngth; long longnum; if ((number >= 0.001) || (number <= -0.001) || (number != number)) { number = Math.pow(0.1,5)*Math.round(Math.pow(10,5)*number); strnum = String.valueOf(number); bigstrnum = " " + strnum + " "; period = bigstrnum.indexOf('.'); substrnum = bigstrnum.substring(period -6, period + 6); if ((number >= 1000000) || (number <= -100000) || (number != number)) substrnum = "big magnitude"; } else { longnum = Math.round(Math.pow(10,5)*number); if (longnum == 0) substrnum = " 0.00000"; else { strnum = String.valueOf(longnum); if (longnum < 0) strnum = strnum.substring(1); lngth = strnum.length(); switch (lngth) { case 1: substrnum = " 0.0000" + strnum; break; case 2: substrnum = " 0.000" + strnum; break; default: substrnum = " error"; } if (longnum < 0) substrnum = " -" + substrnum.substring(5); } } return substrnum; } } //end of SysEu