//	Main class///*   *	Riemann SUm Applet *	By Mike May, S.J., August 2001, revised 2002 *	e-mail: maymk@slu.edu * *	Inspired by an applet of the same name by Brendon Cheves & Bill Ziemer *  e-mail: brendon@csulb.edu  wziemer@csulb.edu *  expr package Copyright 1996 by Darius Bacon  */// Last update 8/16/2002/* *	 *  The applet graphs a function and the Riemann sum approximations of the *	integral over a specified range.  The applet computes six approximations *	(left hand rule, right hand rule, midpoint rule, trapazoid rule, *	Simpson's rule, and Gaussian quadrature) *	for a specified number of subintervals and plots the area of the chosen  *	approximation.  *	 *  The structure of the program has a main class Riemann.   *  The work is broken into a number of visible classes: *  DrawingPanel, FeedbackPanel, HelpArea, and AboutArea. *  The names of these classes are fairly self descriptive. *  The main function and its domain are in the ZFunction class.  *  This ZFunction class uses a parser that calls on the following classes: *  Expr, Parser, Syntax_error, Test, TrivialClass and Variable. *	The subsidaiary classes of FeedbackPanel are InputPanel, ControlPanel, *	OutputPanel, and DomainPanel. *	MultilineLabel is used by AboutArea. *//*   * * public class Riemann extends Applet *	public void init() *	public boolean action(Event e, Object arg) * *	The main applet has a title label and buttons to switch between three *	cards, the main card, the help card, and the about card. *	The about card provides author information. *	The help card gives help that a user may need to run the applet. *	The main card is what we might think of as the applet proper.  It *	contains a drawing panel and a feedback panel.  The drawing panel *	and feedback panel are separate objects where most of the real work is done. *	The domain and range of the drawing panel are contained in the main function. * *	The init method sets up the basic interface though the most of the hard *	details are in the feedback panel and the drawing panel. * *	An action method is needed to deal with the buttons that switch cards. * * *  public void fixMain() *  public void importFeedbackPanelValues() * *	The methods of this class involve when an action in the FeedbackPanel need to be *	updated in both the FeedBackPanel and in the DrawingPanel.  A numer of variables *	need to be sent to the drawing panel for this to work. */// java packagesimport java.applet.*;import java.awt.*;import java.lang.Math;import expr.*;			// f(x) parser by Darius Bacon						// Modified by Mike May, S.J.public class Riemann extends Applet{//  Declare variables	int	 	drawingPanelWidth = 470, drawingPanelHeight = 405;//	GUI elements   			Button 			helpButton, aboutButton, mainButton;	Label 			titleLabel;    CardLayout		theCards;    	    Panel	 		mainCd, mainPanel, cardChoicePanel;    HelpArea		helpText;    AboutArea		aboutText;    FeedbackPanel	feedbackPanel;   	DrawingPanel 	theDrawingPanel;	ZFunction		mainFunction;    public void init()    {		mainFunction = new ZFunction();				this.setLayout(null);		resize(700,500);  	   	//	Set up the pieces		titleLabel = new Label("Riemann Sums", Label.CENTER);		this.add(titleLabel);		titleLabel.setFont(new Font("Dialog", Font.BOLD, 18));		titleLabel.setBounds(125,12,450,24);   	      	    mainPanel = new Panel();   	    this.add(mainPanel);   	    mainPanel.setBounds(10,50,680,405);    	// create a card layout and 3 cards    	theCards = new CardLayout(0,0);		mainPanel.setLayout(theCards); 		// create the main card 		mainCd = new Panel(); 		mainPanel.add("main",mainCd); 		mainCd.setLayout(null); 		// create the about card		aboutText = new AboutArea();   	    aboutText.setBounds(0,0,600,380); 		mainPanel.add("about",aboutText); 		// create the help card		helpText = new HelpArea(600, 300);   	    helpText.setBounds(0,0,600,380); 		mainPanel.add("help",helpText);  		// create the feedback panel and add it to the main cd 		feedbackPanel = new FeedbackPanel(this, mainFunction);   	    feedbackPanel.setBounds(480,0,200,405);		mainCd.add(feedbackPanel); 		feedbackPanel.setLayout(null);						// create the drawing panel and add it to the main cd  		theDrawingPanel = new DrawingPanel(this, mainFunction);   	    theDrawingPanel.setBounds(0,0,drawingPanelWidth,drawingPanelHeight);		mainCd.add(theDrawingPanel);		//	move the data from feedback panel to drawing panel and initialize		feedbackPanel.collectData();		fixMain(); 			/**	 *	Add a panel to the bottom of the screen to let the user choose	 *	between cards.	 */   	    cardChoicePanel = new Panel();   	    this.add(cardChoicePanel);   	    cardChoicePanel.setBounds(200,460,300,20);		cardChoicePanel.setLayout(new GridLayout(1,0,10,0));		mainButton = new Button("Main Panel");		cardChoicePanel.add(mainButton);		helpButton = new Button("Help Panel");		cardChoicePanel.add(helpButton);		aboutButton = new Button("About Panel");		cardChoicePanel.add(aboutButton);		// finally, show the main card		theCards.show(mainPanel,"main");    }   // init     	// handle GUI events    public boolean action(Event e, Object arg)	{     	if(e.target == aboutButton)      	{			theCards.show(mainPanel,"about");      		return true;      	}      	else if(e.target == helpButton)      	{			theCards.show(mainPanel,"help");      		return true;      	}      	else if(e.target == mainButton)      	{			theCards.show(mainPanel,"main");      	    feedbackPanel.collectData();      	    fixMain();        	paint(theDrawingPanel.getGraphics());	   		return true;      	} 		else return super.action(e,arg);		}  //  action    public void fixMain()    {		importFeedbackPanelValues();  	    theDrawingPanel.updateDrawingValues();	   	paint(getGraphics());	    theDrawingPanel.repaint();   }	//	fixMain            public void importFeedbackPanelValues()    {		theDrawingPanel.delX 			= feedbackPanel.delX; 		theDrawingPanel.approxIndex 	= feedbackPanel.approxIndex; 		theDrawingPanel.numParts 		= feedbackPanel.numParts; 		theDrawingPanel.areaPlotState 	= feedbackPanel.areaPlotState; 		theDrawingPanel.numericPlotState= feedbackPanel.numericPlotState; 		theDrawingPanel.guessString 	= feedbackPanel.guessString; 		theDrawingPanel.guessPlotState 	= feedbackPanel.guessPlotState;		theDrawingPanel.guess2PlotState = feedbackPanel.guess2PlotState;    }	//	importfeedbackPanelValues}	//	Riemann//////////////		Other pieces/////////* *	The drawing panel is an object for the graphical display of the applet. * *public class DrawingPanel extends Canvas *	public  DrawingPanel(Riemann riemann) * *	The constructor does little more than extend canvas and identify the applet *	and applet so that information can be passed back and forth. * * * 	public void updateDrawingValues() *	public void getFunctionLimits() * *	This next set of methods do the work of revising values that belong to the  *	DrawingPanel. * *	public void repaint() *	public void paint(Graphics g) *	public void plot(Graphics g, ZFunction f, double leftX, double rightX, Color color) *	public void plotNumAntiDeriv(Graphics g, ZFunction f) *	public void drawRectangles(Graphics g, ZFunction f,  *				double leftX, double rightX,int numParts, double r) *	public void fillRectangles(Graphics g, ZFunction f,  *				double leftX, double rightX,int numParts, double r) *	public void drawTrapezoids(Graphics g, ZFunction f,  *				double leftX, double rightX,int numParts) *	public void fillTrapezoids(Graphics g, ZFunction f,  *				double leftX, double rightX,int numParts) *	public void drawQuadratics(Graphics g, ZFunction f,  *				double leftX, double rightX,int numParts) *	public void drawAxis(Graphics g) *	public void drawLimits(Graphics g) *	public String niceOut(double number, int prec) * *	The repaint method simply gets the graphics and calls paint which does all the work. *  The other methods in this group do parts of the plotting. *	The method niceOut cleans up output formatting. * * *	public double xPixelToReal(double xPixel) *	public double xPixelToReal(int xPixel) *	public int xRealToPixel(double xReal) *	public int xRealToPixel(int xReal) *	public int yRealToPixel(double yReal) *	public int yRealToPixel(int yReal) *	public double yPixelToReal(double yPixel) *	public double yPixelToReal(int yPixel) * *	These methods switch between coordinate and pixel measurements of locations on  *	the graph *	 */ import java.awt.event.*;import java.awt.*;import java.applet.*;public class DrawingPanel extends Canvas{//  Declare variables//	variables concerned with the size of the panel and how much is used //	for the actual drawing.  //	The left and right offsets and the vertical offsets are just to //	make everything look nice.  Nothing important is graphed in the offset//	area.  The panel is set up with a single offset//	at the top and a double one at the bottom of the panel.	int	 	drawingPanelWidth = 470, drawingPanelHeight = 405,			leftXOffset = 40, rightXOffset = 40,			areaXWidth = drawingPanelWidth - leftXOffset - rightXOffset,			YOFFSET = 20;	double  leftX, rightX,  halfHigh, halfWide;//	Variables for items imported or exported	double	delX,			xMin = -5.0, xMax = 5.0, yMin = -5.0, yMax = 5.0; 	int		approxIndex, numParts;	boolean	areaPlotState, numericPlotState, guessPlotState, guess2PlotState;	String	guessString, guess2String;   			ZFunction	theFunction, guessFunction, guess2Function;	Riemann	applet;	public  DrawingPanel(Riemann riemann, ZFunction mainFunction)	{		super();		  	   	theFunction 	= mainFunction;  	   	guessFunction 	= new ZFunction();  	   	guess2Function 	= new ZFunction();		getFunctionLimits();		applet = riemann;	}	//	DrawingPanel	constructor    	public void updateDrawingValues()	{		getFunctionLimits();		guessFunction.parse(guessString);		leftX 	= xMin - (1.0*leftXOffset/areaXWidth)*(xMax-xMin);		rightX	= xMax + (1.0*rightXOffset/areaXWidth)*(xMax-xMin);		if(numParts > 1000) numParts = 1000;		delX = (xMax - xMin)/ numParts;	}	//	updateDrawingValues	public void getFunctionLimits()	{		xMin 	= theFunction.xMin;		xMax 	= theFunction.xMax;   		yMin 	= theFunction.yMin;   		yMax	= theFunction.yMax;	}	//	getFunctionLimits	public void repaint()	{		paint(getGraphics());	}	//	repaint		public void paint(Graphics g)	{	//	clear the canvas		g.clearRect(0,0,drawingPanelWidth,drawingPanelHeight);	//	paint the appropriate approximation		if(areaPlotState == true)		{		    if(approxIndex == 0){		//	Left hand rule				fillRectangles(g,theFunction,xMin, xMax, numParts,0.0);				drawRectangles(g,theFunction,xMin, xMax, numParts,0.0);}		    if(approxIndex == 1){		//	Mid-point rule				fillRectangles(g,theFunction,xMin, xMax, numParts,0.5);				drawRectangles(g,theFunction,xMin, xMax, numParts,0.5);}		    if(approxIndex == 2){		//	Right hand rule				fillRectangles(g,theFunction,xMin, xMax, numParts,1.0);				drawRectangles(g,theFunction,xMin, xMax, numParts,1.0);}		    if(approxIndex == 3){		//	Trapezoid rule				fillTrapezoids(g,theFunction,xMin, xMax, numParts);				drawTrapezoids(g,theFunction,xMin, xMax, numParts);}		    if(approxIndex == 4){		//	Simpson's rule				drawQuadratics(g,theFunction,xMin, xMax, numParts);}		}	//  plot the guess of the antiderivative		if(guessPlotState == true) plot(g, guessFunction, leftX, rightX, Color.cyan);		if(guess2PlotState == true)		{ 			guess2String = guessString + " - " + niceOut(guessFunction.value(xMin),6);			guess2Function.parse(guess2String);			plot(g, guess2Function, leftX, rightX, Color.orange);		}	//	paint the appropriate approximation		if(numericPlotState == true) plotNumAntiDeriv(g, theFunction);	//	plot the function				plot(g, theFunction, leftX, rightX, Color.blue);		//	add axes and limits				drawAxis(g); 		drawLimits(g);	}	//	paint		public void plot(Graphics g, ZFunction f, double leftX, double rightX, Color color)	{		int y1, y2, j;      	g.setColor(color);				f.xvar.set_value(xPixelToReal(leftX));		y1 = yRealToPixel(f.expr.value());				for(int i=xRealToPixel(leftX); i < xRealToPixel(rightX); i++)		{			f.xvar.set_value(xPixelToReal(i+1));			y2 = yRealToPixel(f.expr.value());			// Make sure at least one endpoint is in the visible window 			if(  ((0 <= y2) && (y2 <= drawingPanelHeight)) ||				 ((0 <= y1) && (y1 <= drawingPanelHeight)) ) g.drawLine(i, y1, i+1, y2);						y1 = y2;		}	}  //  plot	public void plotNumAntiDeriv(Graphics g, ZFunction f)	{		int 	y1, y2, x1, x2, j;		double	area = 0.0, leftX, areaSum = 0.0;      	g.setColor(Color.red);				y1 = yRealToPixel(0);		x1 = xRealToPixel(xMin);				if(approxIndex < 4)for(int i=0; i < numParts; i++)		{			leftX = xMin + i*delX;			x2 = xRealToPixel(leftX + delX);			if(approxIndex == 0) area = delX*f.value(leftX);			if(approxIndex == 1) area = delX*f.value(leftX + 0.5*delX);			if(approxIndex == 2) area = delX*f.value(leftX + delX);			if(approxIndex == 3) area = delX*(f.value(leftX) + f.value(leftX+delX))/2.0;			areaSum += area;			y2 = yRealToPixel(areaSum);						// Make sure at least one endpoint is in the visible window 			if(  ((0 <= y2) && (y2 <= drawingPanelHeight)) ||				 ((0 <= y1) && (y1 <= drawingPanelHeight)) ) g.drawLine(x1, y1, x2, y2);			y1 = y2;			x1 = x2;		}		if(approxIndex == 4)for(int i=0; i < numParts/2; i++)		{			leftX = xMin + i*delX*2;			x2 = xRealToPixel(leftX + 2*delX);						area = delX*(f.value(leftX) + 4*f.value(leftX + delX) 					+ f.value(leftX + 2*delX))/3.0;			areaSum += area;			y2 = yRealToPixel(areaSum);						// Make sure at least one endpoint is in the visible window 			if(  ((0 <= y2) && (y2 <= drawingPanelHeight)) ||				 ((0 <= y1) && (y1 <= drawingPanelHeight)) ) g.drawLine(x1, y1, x2, y2);			y1 = y2;			x1 = x2;		}	}  //  plotNumAntiDeriv	public void drawRectangles(Graphics g, ZFunction f, 				double leftX, double rightX,int numParts, double r)	{		int x1,yPoint,x2,y0,h=0, i;		int numParts2 =  numParts;		if(numParts > 1000){numParts2 = 1000;}		double dx = (rightX-leftX)/numParts2;		double xVal1, xVal2;				y0 = yRealToPixel(0); 		//  loop to compute and draw rectangles		for(i = 0; i < numParts2; i ++ )		{			xVal1 = leftX + i*dx;			xVal2 = xVal1 + dx;			x1 = xRealToPixel(leftX + i*dx);			x2 = xRealToPixel(leftX + i*dx + dx);			yPoint = (int)yRealToPixel(f.value(leftX + (i+r)*dx));			g.setColor(Color.darkGray);			g.drawLine(x1,yPoint,x2,yPoint);			g.drawLine(x1,yPoint,x1,y0);			g.drawLine(x2,yPoint,x2,y0);		}  // end of rectangle loop		}  //  drawRectangles	public void fillRectangles(Graphics g, ZFunction f, 				double leftX, double rightX,int numParts, double r)	{		int x1,yPoint,x2,y0, i;		int numParts2 =  numParts;		if(numParts > 1000){numParts2 = 1000;}		double dx = (rightX-leftX)/numParts2;				y0 = yRealToPixel(0); 		//  loop to compute and draw rectangles		for(i = 0; i < numParts2; i ++ )		{			x1 = xRealToPixel(leftX + i*dx);			x2 = xRealToPixel(leftX + i*dx + dx);			yPoint = (int)yRealToPixel(f.value(leftX + (i+r)*dx));						if(yPoint>y0)	// below x axis			{	    	g.setColor(Color.green);			g.fillRect(x1,y0, x2 - x1,yPoint - y0);			}			else			{	    	g.setColor(Color.yellow);			g.fillRect(x1,yPoint, x2 - x1,y0 - yPoint);			}		}  // end of rectangle loop		}  //  fillRectangles	public void drawTrapezoids(Graphics g, ZFunction f, 				double leftX, double rightX,int numParts)	{		int y0,x1,y1,x2,y2, i;		int numParts2 =  numParts;		if(numParts > 1000){numParts2 = 1000;}		double realy1,realy2, xVal1, xVal2;		double dx = (xMax - xMin)/numParts2;				y0 = yRealToPixel(0);		//  regular trapezoids		for(i = 0; i < numParts2; i ++ )		{			xVal1 = xMin + i*dx;			xVal2 = xVal1 + dx;			x1 = xRealToPixel(xVal1);			x2 = xRealToPixel(xVal2);			y1 = (int)yRealToPixel(f.value(xVal1));			y2 = (int)yRealToPixel(f.value(xVal2));						g.setColor(Color.darkGray);			g.drawLine(x1,y1,x2,y2);			g.drawLine(x1,y1,x1,yRealToPixel(0));			g.drawLine(x2,y2,x2,yRealToPixel(0));		}  	}  //  drawTrapezoids	public void fillTrapezoids(Graphics g, ZFunction f, 				double leftX, double rightX,int numParts)	{		int y0,x1,y1,x2,y2, i, tempY;		int numParts2 =  numParts;		if(numParts > 1000){numParts2 = 1000;}		int[] xPoints = new int[4];		int[] yPoints = new int[4];		double dx = (xMax - xMin)/numParts2;				y0 = yRealToPixel(0);		for(i = 0; i < numParts2; i ++ )		{			x1 = xRealToPixel(xMin + i*dx);			x2 = xRealToPixel(xMin + i*dx + dx);			y1 = (int)yRealToPixel(f.value(xMin + i*dx));			y2 = (int)yRealToPixel(f.value(xMin + i*dx + dx));						for(int j= x1 ; j < x2 ; j++)			{				tempY = y1 + (y2 - y1)*(j+1 - x1)/(x2 - x1);				g.setColor(Color.yellow);				if (tempY > y0) g.setColor(Color.green);				g.drawLine(j+1,y0,j+1,tempY);	 		}		}  	}  //  fillTrapezoids	public void drawQuadratics(Graphics g, ZFunction f, 				double leftX, double rightX,int numParts)	{		int y0,x1,y1,x2,y2,x3,y3,tempy1,tempy2, tempy3, j;		int numParts2 =  numParts;		if(numParts > 1000){numParts2 = 1000;}//  be sure that the number of partitions is even		int partsSimpson = numParts2;		if ((numParts % 2) == 1)		   {		   ++partsSimpson;		   System.out.println(		       "Warning - n must be even to use Simpson's rule");		   System.out.println("n has been increased to " + 		       partsSimpson);		    }		int[] xPoints = new int[4];		int[] yPoints = new int[4];		double dx = (rightX-leftX)/partsSimpson;		 		y0 = yRealToPixel(0);				for(j = 0; j < partsSimpson; j += 2 )		{		x1 = xRealToPixel(xMin + j*dx);		y1 = (int)yRealToPixel(f.value(xMin + j*dx));		x2 = xRealToPixel(xMin + (j+1)*dx);		y2 = (int)yRealToPixel(f.value(xMin + (j+1)*dx));		x3 = xRealToPixel(xMin + (j+2)*dx);		y3 = (int)yRealToPixel(f.value(xMin + (j+2)*dx));						// plotting quadratic top		if((x2-x1)>1)		{			g.setColor(Color.black);			tempy1 = y1;								for(int i= x1 ; i < x3 ; i++)			{				tempy2 = 				 y3*((i+1-x1)*(i+1-x2))/((x3-x1)*(x3-x2)) +				 y2*((i+1-x1)*(i+1-x3))/((x2-x1)*(x2-x3)) +				 y1*((i+1-x3)*(i+1-x2))/((x1-x3)*(x1-x2));			g.setColor(Color.yellow);			if (tempy2 > y0) g.setColor(Color.green);				g.drawLine(i+1,y0,i+1,tempy2);			g.setColor(Color.black);				g.drawLine(i,tempy1,i+1,tempy2);				tempy1 = tempy2;	 		}		}		g.setColor(Color.darkGray);				//  draw dotted line at x2				if (y2 < y0 )			for(int i = y2; i < y0-2; i+=8)			      g.drawLine(x2,i,x2,i+4);				else			for(int i = y0; i < y2-2; i+=8)				g.drawLine(x2,i,x2,i+4);											//  draw solid lines at x1 and x3		g.drawLine(x1,y1,x1,y0);		g.drawLine(x3,y3,x3,y0);					}	}  // drawQuadratics	// draw the axis	public void drawAxis(Graphics g)	{	    int xAxisPixel, yAxisPixel;  //     	int x1Pixel = (int) xRealToPixel(x1);       		  	g.setColor(Color.black); 	  	 	  	xAxisPixel = yRealToPixel(0); 	  	if(xAxisPixel > drawingPanelHeight - 50) xAxisPixel = drawingPanelHeight - 50; 	  	if(xAxisPixel < 28) xAxisPixel = 28; 	  	yAxisPixel = leftXOffset;				// x axis        g.drawLine(0,xAxisPixel,drawingPanelWidth - 20,xAxisPixel);	         // y axis        g.drawLine(yAxisPixel,20,                       yAxisPixel,drawingPanelHeight-10);                g.drawString("X",drawingPanelWidth - 15,xAxisPixel + 4);        g.drawString("Y",yAxisPixel-2,17); 	}  //  drawAxis	// draw limits in the proper places	public void drawLimits(Graphics g)	{      	int xAxisPixel, yAxisPixel, xMaxPixel, xMidPixel, yPixel;      	int xBasePixel, x1Pixel;      	double yVal;      	xAxisPixel = (int) yRealToPixel(0); 	  	if(xAxisPixel > drawingPanelHeight - 50) xAxisPixel = drawingPanelHeight - 50; 	  	if(xAxisPixel < 28) xAxisPixel = 28;      	yAxisPixel = leftXOffset;      	xMidPixel  = leftXOffset + areaXWidth/2;      	xMaxPixel  = leftXOffset + areaXWidth;      	g.setColor(Color.red);				// x limit		g.drawString(niceOut(xMin, 4), yAxisPixel + 4,xAxisPixel + 14);		g.drawLine(yAxisPixel,xAxisPixel - 2, yAxisPixel,xAxisPixel + 2);		g.drawString(niceOut((xMin + xMax)/2.0, 4), xMidPixel + 4,xAxisPixel + 14);		g.drawLine(xMidPixel,xAxisPixel - 2, xMidPixel,xAxisPixel + 2);		g.drawString(niceOut(xMax, 4), xMaxPixel + 4,xAxisPixel + 14);		g.drawLine(xMaxPixel,xAxisPixel - 2, xMaxPixel,xAxisPixel + 2);				// y limit		yVal = theFunction.yMax;		yPixel = yRealToPixel(yVal);		g.drawString(niceOut(yVal, 4), yAxisPixel - 40,yPixel + 3);		g.drawLine(yAxisPixel - 2,yPixel, yAxisPixel + 2,yPixel);				yVal = theFunction.yMin;		yPixel = yRealToPixel(yVal);		g.drawString(niceOut(yVal, 4), yAxisPixel - 40,yPixel + 3);		g.drawLine(yAxisPixel - 2,yPixel, yAxisPixel + 2,yPixel);				  	}  //  drawLimits			// Return number rounded to desired precision	public String niceOut(double number, int prec)	{   	     int firstDigit, shift, precision = prec;	     firstDigit = (int)(Math.floor(Math.log(number) /                  Math.log(10.0)));	     shift = - firstDigit + precision - 1;	     if (number == 0) return "0.0";	     else return String.valueOf((Math.round(number*(Math.pow(10,shift))))/                  (Math.pow(10,shift)));	}	//	niceOut		// input pixel, output real value in interval [xMIn, xMax]	public double xPixelToReal(double xPixel)	{		return ((xPixel - leftXOffset) * (xMax - xMin) / 		            areaXWidth + xMin);	}  //  xPixelToReal		public double xPixelToReal(int xPixel)	{		return ((xPixel - leftXOffset) * (xMax - xMin) / 		            areaXWidth + xMin);	}  //  xPixelToReal	// input real, output pixel in interval [0, XSCALE]	public int xRealToPixel(double xReal)	{		return (int)((xReal - xMin) / 		              (xMax - xMin) * areaXWidth + leftXOffset);	}  //  xRealToPixel	public int xRealToPixel(int xReal)	{		return (int)((xReal - xMin) / 		              (xMax - xMin) * areaXWidth + leftXOffset);			}  //  xRealToPixel	// input real value, output pixel in interval [0, YSCALE]	public int yRealToPixel(double yReal)	{		return (int)((yReal - yMax) * (drawingPanelHeight - 3*YOFFSET) / 		         (yMin - yMax) + YOFFSET);	}  //  yRealToPixel	public int yRealToPixel(int yReal)	{		return (int)((yReal - yMax) * (drawingPanelHeight - 3*YOFFSET) / 		        (yMin - yMax) + YOFFSET);	}  //  yRealToPixel	// input pixel, output real in interval [yMin, yMax]	public double yPixelToReal(double yPixel)	{		return ((yPixel - YOFFSET) * (yMin - yMax) / 		        (drawingPanelHeight - 3*YOFFSET) + yMax);	}  //  yPixelToReal	public double yPixelToReal(int yPixel)	{		return ((yPixel - YOFFSET) * (yMin - yMax) / 		        (drawingPanelHeight - 3*YOFFSET) + yMax);	}  //  yPixelToReal}	//	DrawingPanel class// ZFunction Class/*  Modified by Mike May,  August 2002 *	Inspired by a class witten Bill Ziemer and Brendon Cheves *	that was based upon the Java Polygon class *	 *	public class ZFunction	public ZFunction() *	public void parse( String f ) *	 *	The class ZFuncttion is a subsidiary class of DrawingPanel. *	the parse method sends the string over to the Parser class for parsing *	 * *	public double value(double x) *	public double findNumDeriv(double x, double xDel) *	public double findDifferenceQuotient(double xa, double xb) *	public void findNumDerivs(double xBase, double xDel) *	 *	These methods either evaluate the function at X or evaluate difference *	quotients related to the function. * *	 *	public void determineYMinYMax() *	public void setYRange(double f, double l) *	public void setXRange(double f, double l) * *	The last three methods are useful in setting finding appropriate limits *	to use when graphing the function. */// java packagesimport java.applet.*;import java.awt.*;import java.lang.Math;import expr.*;	// expr package Copyright 1996 by Darius Baconpublic class ZFunction{	//Real number bounds for the function	public double yMin = -5.0, yMax = 5.0;	public double xMin = -5.0, xMax = 5.0;	public double zeroDeriv, firstDeriv, secSlope, leftSlope; 	//	created for access to infinity constants	Double doubleCheck = new Double(1.0);	 	public Expr expr, linApprox;	public Variable xvar;	public double realArea, areaSum, fixedpt;	int iterate, endit, changer;	public ZFunction()	{		// set up the parsing variables		xvar = Variable.make("x");		Variable.make("pi").set_value (Math.PI);			Variable.make("PI").set_value (Math.PI);			Variable.make("Pi").set_value (Math.PI);			Variable.make("e").set_value (Math.exp(1));	/* * 	Õ and e are not in the parsing constructor */	}  //  ZFunction constructor		/*	 *	Parse the function	 */	 	public void parse( String f ) 	{	   	try	   	{expr = Parser.parse(f);}		catch (Syntax_error se)		{			System.err.println ("Syntax error: " + se);			return;		}	}  // parse		public double value(double x)	{		xvar.set_value(x);		return expr.value();	}  //  value 				public double findNumDeriv(double x, double xDel)	{		return findDifferenceQuotient(x - xDel, x + xDel);	}	//	findNumDerivs 			public double findDifferenceQuotient(double xa, double xb)	{		return (value(xb) - value(xa))/(xb - xa);	}	//	findNumDerivs			public void findNumDerivs(double xBase, double xDel)	{		zeroDeriv 	= value(xBase);		firstDeriv	= findDifferenceQuotient(xBase + xDel, xBase - xDel);		secSlope 	= findDifferenceQuotient(xBase + xDel, xBase);		leftSlope 	= findDifferenceQuotient(xBase, xBase - xDel);	}	//	findNumDerivs			public void determineYMinYMax()	{		double dx = (xMax-xMin)/500.0, tempY;				yMin = doubleCheck.POSITIVE_INFINITY;		yMax = doubleCheck.NEGATIVE_INFINITY;				for(int i=0;i<=500;i++)		{			tempY = value(xMin + i*dx);			if(tempY > yMax) 		yMax = tempY;						if(tempY < yMin)	yMin = tempY;		}		//	Round to three decimal places		yMax = ((int)(yMax*1000))/1000.0;		yMin = ((int)(yMin*1000))/1000.0;		//	Fudge things so that the X-axis is included		if (yMin > -.5) yMin = -.5;		if (yMax < 0.5) yMax = 0.5;	}  //  determineYminYMax	 	// set y range manually	public void setYRange(double f, double l)	{		yMin = f;		yMax = l;	}  //  setYRange		// set x range manually	public void setXRange(double f, double l)	{		xMin = f;		xMax = l;	}  //  setXRange	} // end of ZFunction Class/* *	The feedback panel is intended to contain all the inputs and text *	outputs used by the applet.   * *public class FeedbackPanel extends Panel *	public FeedbackPanel(SecantTangent secantTangent) *	public void collectData()	public void internalFeedbackPanelComputations() *	public void update() *	public void resetYBounds() *  public void getInputValues() *	public void sendInputValues() *  public void getDomainValues() *	public void sendDomainValues() *  public void getControlValues() *	public void sendOutputValues() * *	It is broken into four subpanels, one each for: user supplied inputs, *	the domain and range of the graph, control values of what will be graphed, *	and for output.  There may be a get and send method for each subpanel. *	The fixInputs method collects data from all panels.  The *	internalFeedbackPanelComputations method does the obvious things. *	The update, resetFunction, and resetYbounds methods are there to invoke  *	methods in the panel that contains the FeedbackPanel.  The newExampleChosen *	method resets controls when one of the canned examples is selected. * * *public class InputPanel extends Panel *	public InputPanel(FeedbackPanel fPanel, ZFunction mainFunction) *	class SymItem2 implements java.awt.event.ItemListener *  public boolean action(Event e, Object arg) *	public void shiftFunctionStringForExample() *	public void collectInputValues() *	public void postInputValues() * *public class ControlPanel extends Panel *	public ControlPanel(FeedbackPanel fPanel) *	class SymItem implements java.awt.event.ItemListener *		public void itemStateChanged(java.awt.event.ItemEvent event) *	public void collectControlValues() * *public class OutputPanel extends Panel *	public OutputPanel() *	public void postOutput() * *public class DomainPanel extends Panel *	public DomainPanel(FeedbackPanel fPanel) *  public boolean action(Event e, Object arg) *	public void functionDomainToDomainPanel() *	public void domainPanelToFunctionDomain() *	public void postDomainValues() *	public void collectDomainValues() * * *	In addition to its constructor, each of the four subpanels may have an action *	listener, a method to respond to actions, and methods to collect and post data. *	The domain panel also needs to communicate domain information with the main *	function in the problem. */import java.awt.*;import java.applet.*;import MIO.*;public class FeedbackPanel extends Panel{	/*	 *		Public variables that are either inputs or outputs to be passed	 */	double	leftArea, midArea, rightArea, trapezoidArea, 			simpsonArea, quadratureArea, delX,			xMin = -5.0, xMax = 5.0; 	int		approxIndex, numParts;	boolean	areaPlotState, numericPlotState, guessPlotState, guess2PlotState;    String	functionString, guessString;        ZFunction	f;	InputPanel		inputPanel;	ControlPanel	controlPanel;	OutputPanel		outputPanel;	DomainPanel		domainPanel;	Riemann 	applet;	public FeedbackPanel(Riemann riemann, ZFunction mainFunction)	{	/*	 *	To set up the Feedback panel, we need to create the 4 subpanels,	 *	then create a function to use, and set the initial example.	 */		this.setLayout(null);		applet = riemann;		f = mainFunction;    	    inputPanel = new InputPanel(this, mainFunction);    	inputPanel.setBounds(0,0,200,120); 		inputPanel.setLayout(null);		this.add(inputPanel);   	    outputPanel = new OutputPanel();    	outputPanel.setBounds(0,120,200,100); 		outputPanel.setLayout(null);		this.add(outputPanel);   	    controlPanel = new ControlPanel(this);    	controlPanel.setBounds(0,220,200,100); 		controlPanel.setLayout(null);		this.add(controlPanel);   	    domainPanel = new DomainPanel(this, mainFunction);   	    domainPanel.setBounds(0, 340, 200, 60);  		domainPanel.setLayout(null);		this.add(domainPanel);				newExampleChosen();	}	//	FeedbackPanel	//		Gather the inputs - main collection method		public void collectData()    {			getInputValues();			getDomainValues();			getControlValues();			internalFeedbackPanelComputations();			sendInputValues();			sendOutputValues();    }	//	  collectData	public void internalFeedbackPanelComputations()	{		double	leftX;		int		i;			if (((numParts % 2) == 1)&&(approxIndex == 4))		   {		   ++numParts;		   System.out.println(		       "Warning - n must be even to use Simpson's rule");		   System.out.println("n has been increased to " + 		       numParts);		    }	//	set the width of the subintervals and set the function		delX = (xMax - xMin)/numParts;	//	zero out the approximations		leftArea		= 0.0;		midArea			= 0.0;		rightArea		= 0.0;		trapezoidArea	= 0.0;		simpsonArea		= 0.0;		quadratureArea	= 0.0;	//	add the appropriate y values for the approximations		for(i = 0; i < numParts; i ++ )		{			leftX = xMin + i*delX;			leftArea		+= f.value(leftX);			midArea			+= f.value(leftX + 0.5*delX);			rightArea		+= f.value(leftX + delX);			quadratureArea	+= .5*(.236926885*f.value(leftX + .046910077*delX)								+ .4786286705*f.value(leftX + .230765345*delX)								+ .5688888889*f.value(leftX + .5*delX)								+ .4786286705*f.value(leftX + .769234655*delX)								+ .236926885*f.value(leftX + .953089923*delX));		}		for(i = 0; i < numParts/2; i ++ )		{			leftX = xMin + i*delX*2;			simpsonArea	+= f.value(leftX) + 4*f.value(leftX + delX) + f.value(leftX + 2*delX);		}	//	multiply the weighted sum of y values by the width of a subinterval	//		to get the approximation.		leftArea		= leftArea*delX;		midArea			= midArea*delX;		rightArea		= rightArea*delX;		trapezoidArea	= (leftArea + rightArea)/2.0;		simpsonArea		= simpsonArea*delX/3.0;		quadratureArea	= quadratureArea*delX;	}	//	internalFeedbackPanelComputations		public void update()	{	      	applet.fixMain();	}	//	update	public void resetYBounds()	{		f.determineYMinYMax();		domainPanel.functionDomainToDomainPanel();		domainPanel.postDomainValues();	}	//	resetYBounds   	    //		Methods for communicating with subsidiary objects    public void getInputValues()    {   	    inputPanel.collectInputValues();		numParts 		= inputPanel.numParts;		guessString		= inputPanel.guessString;    }	//	getInputValues	public void sendInputValues()	{		inputPanel.delX		= delX;		inputPanel.numParts	= numParts;		inputPanel.postInputValues();	}	//	sendInputValues	    public void getDomainValues()    {	    domainPanel.collectDomainValues();		xMin = f.xMin;		xMax = f.xMax;    }	//	getDomainValues    public void getControlValues()    {	    controlPanel.collectControlValues();		approxIndex 		= controlPanel.approxIndex;		areaPlotState 		= controlPanel.areaPlotState;		numericPlotState	= controlPanel.numericPlotState;		guessPlotState 		= controlPanel.guessPlotState;		guess2PlotState 	= controlPanel.guess2PlotState;    }	//	getControlValues	public void sendOutputValues()	{ 		outputPanel.numParts 		= numParts;		 		outputPanel.leftArea 		= leftArea;		 		outputPanel.midArea 		= midArea;		 		outputPanel.rightArea 		= rightArea;		 		outputPanel.trapezoidArea 	= trapezoidArea;		 		outputPanel.simpsonArea 	= simpsonArea;		 		outputPanel.quadratureArea 	= quadratureArea;		 		outputPanel.postOutput();			}  //sendOutputValues 		public void newExampleChosen()	{	/*	 *	When a new example is chosen, the function string must be changed.	 *	New values for the domain limits need to be sent to the domain panel.	 */		inputPanel.shiftFunctionStringForExample();		domainPanel.functionDomainToDomainPanel();		domainPanel.postDomainValues();	}	//	newExampleChosen}	//	FeedbackPanel class////	Start new subsidiary classpublic class InputPanel extends Panel{	/*	 *		Public variables that are either inputs or outputs to be passed	 */	double	delX; 	int		numParts;    String	functionString, guessString;;  	/*	 *		GUI elements for the panel	 */			Button		doubleNButton, resetNButton;	Choice 		exampleChoice; 	int			exampleIndex;	Label   	fxLabel, numPartsLabel, delXLabel, guessLabel, guessLabel2;    TextField 	functionFld, numPartsField, guessField;     double		xMin, xMax, yMin, yMax;        ZFunction	f;	/*	 *		static variable used in canned examples that can be chosen	 */	 	static		String[]  exampleStrings = {"x+0.1*x^2-3*sin(x)", "2*x+7",					"(x-1)*(x-2)", "(x-1)*(x-2)*(x-3)", "(x-1)*(x-2)*(x-3)*(x-5)", 					"1/sqrt(abs(x-2))", "1/abs(x-2)", "sin(x)+2*cos(3*x)", "exp(x)",					"1/sqrt(2*Pi)*exp(-x^2/2)", "x+0.1*x^2-3*sin(x)"};	static		double[]						exampleXMins ={-5.0, 0.0, 0.0, 0.0, 0.0, 							1.0, 1.0, 0.0, -1.0, -3.0, -5.0},					exampleXMaxs ={5.0, 5.0, 5.0, 5.0, 5.0, 							4.0, 4.0, 6.0, 2.0, 3.0, 5.0},					exampleYMins ={-7.0, -1.0, -1.0, -6.0, -7.0,							-1.0, -1.0, -4.0, -0.5, -0.2, -7.0},					exampleYMaxs ={15.0, 20.0, 15.0, 25.0, 30.0, 							5.0, 10.0, 4.0, 8.0, 0.5, 15.0};						FeedbackPanel  feedbackPanel;	public InputPanel(FeedbackPanel fPanel, ZFunction mainFunction)	{	/*	 *	The Input panel contains information on the function graphed,	 *	the number of subintervals, the size of the subintervals,	 *	the guessed anit-derivative, and the choice of canned	 *	examples to start with.	 */		feedbackPanel = fPanel;		f = mainFunction;		fxLabel = new Label("f(x) = ");		fxLabel.setBounds(0,0,35,18);		this.add(fxLabel);		functionFld = new TextField(exampleStrings[0], 30);		functionFld.setBounds(35,0,165,18);		this.add(functionFld);		numPartsLabel = new Label("The number of partitions is ");		numPartsLabel.setBounds(0,20,150,18);		this.add(numPartsLabel);		numPartsField = new TextField("2", 6);		numPartsField.setBounds(150,20,50,18);		this.add(numPartsField);				doubleNButton = new Button("Double n");    	doubleNButton.setBounds(0,40,50,16);		this.add(doubleNButton);		resetNButton = new Button("Reset n");    	resetNButton.setBounds(55,40,40,16);		this.add(resetNButton);				delXLabel = new Label("del X = ");		delXLabel.setBounds(100,44,100,14);		this.add(delXLabel); 		exampleChoice = new Choice();		exampleChoice.addItem("Original Example"); 		exampleChoice.addItem("Linear Example"); 		exampleChoice.addItem("Quadratic Example"); 		exampleChoice.addItem("Cubic Example"); 		exampleChoice.addItem("Quartic Example");		exampleChoice.addItem("Singularity Example 1");		exampleChoice.addItem("Singularity Example 2");		exampleChoice.addItem("Trig Example");		exampleChoice.addItem("Exponential Example");		exampleChoice.addItem("Normal Curve Example");		exampleChoice.select(0);		exampleChoice.setBounds(0,60,150,18);		this.add(exampleChoice);		guessLabel = new Label("Guessed integral ");		guessLabel.setBounds(50,80,120,14);		this.add(guessLabel);		guessLabel2 = new Label("G(x) = ");		guessLabel2.setBounds(0,96,35,18);		this.add(guessLabel2);		guessField = new TextField("x", 30);		guessField.setBounds(35,96,165,18);		this.add(guessField); 				SymItem2 lSymItem2 = new SymItem2();		exampleChoice.addItemListener(lSymItem2);	}	//	InputPanel// handle GUI events	//	listen for changes in menues		class SymItem2 implements java.awt.event.ItemListener	{		public void itemStateChanged(java.awt.event.ItemEvent event)		{	//	Appropriate action to change the graphed example to a 			//	new preset example.       	    feedbackPanel.newExampleChosen();       	    feedbackPanel.collectData();      	    feedbackPanel.update();    	}	}	//	SymItem class		//	listen for button pushes and returns in text fields    public boolean action(Event e, Object arg)	{      	if((e.target == numPartsField)||      		(e.target == guessField))      	{     	    feedbackPanel.collectData();    		feedbackPanel.update();      		return true;      	}       	if(e.target == functionFld)      	{      	    feedbackPanel.collectData(); 			feedbackPanel.resetYBounds();     		feedbackPanel.update();      		return true;      	}   		if(e.target == doubleNButton)      	{      		numParts = numParts*2;			numPartsField.setText(Integer.toString(numParts));     	    feedbackPanel.collectData();    		feedbackPanel.update();      		return true;      	}   		if(e.target == resetNButton)      	{      		numParts = 2;			numPartsField.setText("2");     	    feedbackPanel.collectData();    		feedbackPanel.update();      		return true;      	} 		else return super.action(e,arg);		}  //  action//		Shfit the function string when a new example is chosen	public void shiftFunctionStringForExample()	{	exampleIndex 	= exampleChoice.getSelectedIndex();	functionString 	= exampleStrings[exampleIndex];	functionFld.setText(functionString);	f.parse(functionString);	xMin = exampleXMins[exampleIndex];	xMax = exampleXMaxs[exampleIndex];	f.setXRange(xMin, xMax);	yMin = exampleYMins[exampleIndex];	yMax = exampleYMaxs[exampleIndex];	f.setYRange(yMin, yMax);	}	//shiftFunctionStringForExample//		Gather the inputs - main collection method		public void collectInputValues()    {	    numParts=Mio.intFromTextField(numPartsField);	    if (numParts < 1)     	{ 	      System.out.println("Warning, the number of partitions");	       System.out.println("should be at positive");	       numParts = 1;	       numPartsField.setText(Integer.toString(numParts));   		}	    else if (numParts > 100000)     	{	       System.out.println("Warning, the number of partitions");	       System.out.println("should be at most 100000.");	       numParts = 100000;	       numPartsField.setText(Integer.toString(numParts));     	}    	functionString 	= functionFld.getText();		f.parse(functionString);   		guessString 	= guessField.getText();//		g.parse(guessString);    }	//	  collectInputValues	public void postInputValues()    {		numPartsField.setText(Integer.toString(numParts));		delXLabel.setText("delX = " + Mio.doubleToStringSigFigures(delX, 5));    }	//	  postInputValues}	//	InputPanel class	////	Start new subsidiary classpublic class ControlPanel extends Panel{	/*	 *		Public variables that are either inputs or outputs to be passed	 */	int			approxIndex;	boolean		areaPlotState, numericPlotState, guessPlotState, guess2PlotState;  	/*	 *		GUI elements for the panel	 */		Choice 		approxChoice; 	Checkbox	areaPlotBox, numericPlotBox, guessPlotBox, guess2PlotBox;	FeedbackPanel  feedbackPanel;	public ControlPanel(FeedbackPanel fPanel)	{		feedbackPanel = fPanel; 		 		approxChoice = new Choice(); 		approxChoice.addItem("Plot Left Hand Rule"); 		approxChoice.addItem("Plot Midpoint Rule"); 		approxChoice.addItem("Plot Right Hand Rule"); 		approxChoice.addItem("Plot Trapezoid Rule"); 		approxChoice.addItem("Plot Simpsons Rule");		approxChoice.select(0);		approxChoice.setBounds(0,0,150,18);		this.add(approxChoice);		areaPlotBox = new Checkbox("Show area approx ", true);		areaPlotBox.setBounds(0,20,150,18);		this.add(areaPlotBox);		numericPlotBox = new Checkbox("Plot numeric F(x) ", false);		numericPlotBox.setBackground(Color.red);		numericPlotBox.setBounds(0,40,150,18);		this.add(numericPlotBox);		guessPlotBox = new Checkbox("Plot G(x) ", false);		guessPlotBox.setBackground(Color.cyan);		guessPlotBox.setBounds(0,60,150,18);		this.add(guessPlotBox);		guess2PlotBox = new Checkbox("Plot G(x) - G(xMin) ", false);		guess2PlotBox.setBackground(Color.orange);		guess2PlotBox.setBounds(0,80,150,18);		this.add(guess2PlotBox);		SymItem lSymItem = new SymItem();		approxChoice.addItemListener(lSymItem);		areaPlotBox.addItemListener(lSymItem);		numericPlotBox.addItemListener(lSymItem);		guessPlotBox.addItemListener(lSymItem);		guess2PlotBox.addItemListener(lSymItem);	}	//	ControlPanel// handle GUI events	//	listen for changes in menues		class SymItem implements java.awt.event.ItemListener	{		public void itemStateChanged(java.awt.event.ItemEvent event)		{       	    feedbackPanel.collectData();      	    feedbackPanel.update();    	}	}	//	SymItem class	//		Gather the inputs - main collection method		public void collectControlValues()    {			approxIndex 		= approxChoice.getSelectedIndex();			areaPlotState 		= areaPlotBox.getState();			numericPlotState	= numericPlotBox.getState();			guessPlotState 		= guessPlotBox.getState();			guess2PlotState 		= guess2PlotBox.getState();    }	//	  collectControlValues}	//	ControlPanel class////	Start new subsidiary classpublic class OutputPanel extends Panel{	/*	 *		Public variables that are either inputs or outputs to be passed	 */	double	leftArea, midArea, rightArea, trapezoidArea, 			simpsonArea, quadratureArea;	int		numParts;   	/*	 *		GUI elements for the panel	 */		Label 	leftAreaLabel, midAreaLabel, rightAreaLabel, trapezoidAreaLabel,			simpsonAreaLabel, quadratureAreaLabel;		public OutputPanel()	{		leftAreaLabel = new Label("Left Hand Area   = ");		leftAreaLabel.setBounds(0,0,180,14);		this.add(leftAreaLabel);		midAreaLabel = new Label("Midpoint Area   = ");		midAreaLabel.setBounds(0,14,180,14);		this.add(midAreaLabel);		rightAreaLabel = new Label("Right Hand Area   = ");		rightAreaLabel.setBounds(0,28,180,14);		this.add(rightAreaLabel);		trapezoidAreaLabel = new Label("Trapezoid Area   = ");		trapezoidAreaLabel.setBounds(0,42,180,14);		this.add(trapezoidAreaLabel);		simpsonAreaLabel = new Label("Simson's Area   = ");		simpsonAreaLabel.setBounds(0,56,180,14);		this.add(simpsonAreaLabel);		quadratureAreaLabel = new Label("Quadrature Area   = ");		quadratureAreaLabel.setBounds(0,70,180,14);		this.add(quadratureAreaLabel);	}		public void postOutput()	{//		Adjust with round to get desired precision		leftAreaLabel.setText("Left Hand Area = " + Mio.doubleToStringSigFigures(leftArea, 6));		midAreaLabel.setText("Midpoint Area = " + Mio.doubleToStringSigFigures(midArea, 6));		rightAreaLabel.setText("Right Hand Area = " + Mio.doubleToStringSigFigures(rightArea, 6));		trapezoidAreaLabel.setText("Trapezoid Area = " + Mio.doubleToStringSigFigures(trapezoidArea, 6));		simpsonAreaLabel.setText("Simson's Area = " + Mio.doubleToStringSigFigures(simpsonArea, 6));		if ((numParts % 2) == 1) simpsonAreaLabel.setText("Simson's Area = ");		quadratureAreaLabel.setText("Quadrature Area = " + Mio.doubleToStringSigFigures(quadratureArea, 6));	}  //	postOutput }	//	outputPanel class////	Start new subsidiary classpublic class DomainPanel extends Panel // Unchanged{	/*	 *		Public variables that are either inputs or outputs to be passed	 */	double  yMin = -5.0, yMax = 5.0, xMin = -5.0, xMax = 5.0; 	/*	 *		Variables that are used in internal computations	 */    double	xCenter, halfWide, yCenter, halfHigh;  	/*	 *		GUI elements for the panel	 */			Button		zoomIn, zoomOut, zSquare, yReset;	Label   	xMinLabel, xMaxLabel, yMinLabel, yMaxLabel;     TextField 	xMinField, xMaxField, yMinField, yMaxField;         ZFunction	f;	FeedbackPanel  feedbackPanel;		public DomainPanel(FeedbackPanel fPanel, ZFunction mainFunction)	{		this.setLayout(null);		feedbackPanel = fPanel;		f = mainFunction;//  	Assume panel is 200 by 60 		xMinLabel = new Label("xMin =");   	    xMinLabel.setBounds(0, 20, 40, 18);		this.add(xMinLabel);		xMinField = new TextField("-5.0", 7);   	    xMinField.setBounds(45, 20, 50, 18);		this.add(xMinField);		xMaxLabel = new Label("xMax =");   	    xMaxLabel.setBounds(0, 0, 40, 18);		this.add(xMaxLabel);		xMaxField = new TextField("5.0", 7);   	    xMaxField.setBounds(45, 0, 50, 18);		this.add(xMaxField);		zoomIn = new Button("Zoom In");    	zoomIn.setBounds(0,40,45,18);		this.add(zoomIn); 		zoomOut = new Button("Zoom Out");    	zoomOut.setBounds(50,40,50,18);		this.add(zoomOut); 		yReset = new Button("Reset Y");    	yReset.setBounds(105,40,45,18);		this.add(yReset); 		zSquare = new Button("Square");    	zSquare.setBounds(155,40,45,18);		this.add(zSquare); 		yMinLabel = new Label("yMin =");   	    yMinLabel.setBounds(100, 20, 40, 18);		this.add(yMinLabel);		yMinField = new TextField("-5.0", 7);   	    yMinField.setBounds(145, 20, 50, 18);		this.add(yMinField);		yMaxLabel = new Label("yMax =");   	    yMaxLabel.setBounds(100, 0, 40, 18);		this.add(yMaxLabel);		yMaxField = new TextField("5.0", 7);   	    yMaxField.setBounds(145, 0, 50, 18);		this.add(yMaxField);	}	//	DomainPanel	//	listen for button pushes and returns in text fields    public boolean action(Event e, Object arg)	{      	if((e.target == xMinField)||(e.target == xMaxField)||      	   (e.target == yMinField)||(e.target == yMaxField))      	{       	    feedbackPanel.collectData();      	    feedbackPanel.update();      		return true;      	}     	      	if((e.target == yReset))      	{      	    feedbackPanel.getInputValues();      	    f.determineYMinYMax(); 	     	functionDomainToDomainPanel();      	    postDomainValues();      	    feedbackPanel.update();      		return true;      	}      	   		if(e.target == zoomIn)      	{      		xCenter = (xMax + xMin)/2;      		halfWide = xMax - xCenter;       		yCenter = (yMax + yMin)/2;      		halfHigh = yMax - yCenter;			xMin = xCenter - halfWide/2.0;			xMax = xCenter + halfWide/2.0;			yMin = yCenter - halfHigh/2.0;			yMax = yCenter + halfHigh/2.0;      	    postDomainValues();       	    feedbackPanel.collectData();      	    feedbackPanel.update();      		return true;      	}   		if(e.target == zoomOut)      	{      		xCenter = (xMax + xMin)/2;      		halfWide = xMax - xCenter;      		yCenter = (yMax + yMin)/2;      		halfHigh = yMax - yCenter;			xMin = xMin - halfWide;			xMax = xMax + halfWide;			yMin = yMin - halfHigh;			yMax = yMax + halfHigh;      	    postDomainValues();       	    feedbackPanel.collectData();      	    feedbackPanel.update();      		return true;      	}   		if(e.target == zSquare)      	{      		halfWide = (xMax - xMin)/2;      		yCenter = (yMax + yMin)/2;			yMin = yCenter - halfWide;			yMax = yCenter + halfWide;      	    postDomainValues();      	    feedbackPanel.update();      		return true;      	} 		else return super.action(e,arg);		}  //  action		public void functionDomainToDomainPanel()	{		xMin = f.xMin;		xMax = f.xMax;		yMin = f.yMin;		yMax = f.yMax;	}	//functionDomainToDomainPanel	public void domainPanelToFunctionDomain()	{		f.setXRange(xMin, xMax);		f.setYRange(yMin, yMax);	}	//	domainPanelToFunctionDomain	public void postDomainValues()	{		domainPanelToFunctionDomain();    	xMinField.setText(Mio.doubleToStringSigFigures(xMin,5));     	xMaxField.setText(Mio.doubleToStringSigFigures(xMax,5));     	yMinField.setText(Mio.doubleToStringSigFigures(yMin,5));     	yMaxField.setText(Mio.doubleToStringSigFigures(yMax,5));	}	//	postDomainValues		public void collectDomainValues()	{	    //  Check that xMin < xMax and set them	    xMin=Mio.doubleFromTextField(xMinField);	   	xMax=Mio.doubleFromTextField(xMaxField);	    if (xMax <= xMin)  	    { 	      System.out.println("Warning, xMin should be < xMax");       	  System.out.println("xMin and xMax reset to defaults.");       		xMin = -5.0;       		xMax = 5.0;       	}    	//  Check that xMin < xMax and set them    	yMin=Mio.doubleFromTextField(yMinField);    	yMax=Mio.doubleFromTextField(yMaxField);    	if (yMax <= yMin)        	{       	  System.out.println("Warning, yMin should be < yMax");       	  System.out.println("xMin and xMax reset to defaults.");       		yMin = -5.0;       		yMax = 5.0;       	}		domainPanelToFunctionDomain();       	postDomainValues();    }  //  collectDomainValues	}	//	DomainPanelClass//	End of FeedbackPanel File/* *	Help are is a simple object to be used for the help panel of the applet. *	It is set up as a scrolling region in case the help text is made long *	enough to require that, but the default is that no scrollbars are visible. */import java.awt.TextArea;public class HelpArea extends TextArea{	public HelpArea(int width, int height)	{//Scrollbar visibility - 0 = both, 1= vert only, 2=horizon only, 3 = none//		super(String text, int width, int height, int scrollbarVisibility)		super(" ", width, height, 1);			this.setText(		"This applet is designed to explore a variety of numeric integration techniques\n" + 		"and topics in a standard course in single variable calculus.\n\n" +				"The user specifies the function, the limits of integration, the number of subintervals,\n" +		" and a method of numeric approximation to be used.  A number of pre-set examples can be selected.\n\n" +				"The applet graphs the interval to be measured by integration as well as the region measured\n" +		" by the method of approximation.  The applet gives the numeric value of the approximations \n" +		"obtained with 6 different approxiamtion methods.\n\n" +				"The number of subintervals must be between 2 and 100,000.\n" +		"Theprogram will only try drawing up to 1000 partitions.\n\n" +		"The user has the option of plotting the graph of the numeric antiderivative\n" +		"as well as plotting the graph of a formula that is \n" +		"the user's guess of the antiderivative.\n\n" +		"Buttons allow the user to double or reset the number of partitions to see the limiting \n" +		"process visually.\n\n" +		"The user can also zoom in or zoom out and can adjust the graph region\n" +		"so that is is square or so that in includes the graph and the axes.\n\n" +				"It should be noted that both the range setting and the evaluation of the numeric\n" +		"derivatives are done with numeric evaluation.  If the function is undefined\n" +		"in the graphed domain, unpredictable results will occur.\n\n" +		"The function should be an expression in x.  Implicit multiplication is not allowed.\n" +		"(Use 3*x rather than 3x.)  Exponentiation is indicated by ^.  \n" +		"The mathematical constant pi can be in upper or lower case.\n" +  		"The constant e is indicated by either e or exp(1).\n" + 		"(These constants only have double precision,  Thus e^x will only appoximate exp(x).\n" + 		"Trig functions are in radians.  Use the functions toDegrees and toRadians to convert.\n\n" +		"The functions understood by the parser are:\n" +		"sin,  cos, tan, sec, csc, acos or arccos, asin or arcsin, atan or arctan, \n" +		"toDegrees, toRadians, abs, ceil, floor, round,\n" +		"sqrt, exp, log or ln (for natural log), and log10.\n\n" +		"Each of these functions requires one argument enclosed in parentheses."		); 		this.setEditable(false);	}}	//	HelpArea/* *	AboutArea is an object for the About Panel.  It is a multi-line label *	with a fixed text message. */import java.awt.*;public class AboutArea extends MultiLineLabel{	Font theFont = new Font("TimesRoman", Font.BOLD, 18);	String label = "Riemann Sum Applet\n \n"+			"Copyright 2001, 2002 by Mike May, S.J.\n"+			"maymk@slu.edu\n \n"+			"Inspired by an applet of the same name by\n"+			"Bill Ziemer and Brendon Cheves\n"+			"Copyright 1996 by California State University," +			    " Long Beach\n \n"+			"Function Parsing Copyright 1996 by Darius Bacon";	int		alignment = 1;		//	center	int		margin_width =10, margin_height = 10;	public AboutArea(){//		super(label, margin_width, margin_height, alignmnet);//		Possible alignment values are 0 for left, 1 for center and 2 for right.		super(" ", 10,10, 1);		this.setLabel(label);		this.setFont(theFont);	}}	//	AboutArea//	MultiLineLabel// This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com)// Copyright (c) 1997 by David Flanagan// This example is provided WITHOUT ANY WARRANTY either expressed or implied.// You may study, use, modify, and distribute it for non-commercial purposes.// For any commercial use, see http://www.davidflanagan.com/javaexamplesimport java.awt.*;import java.util.*;/** * A custom component that displays multiple lines of text with specified * margins and alignment.  In Java 1.1, we could extend Component instead * of Canvas, making this a more efficient "Lightweight component" */public class MultiLineLabel extends Canvas {  // User-specified attributes  protected String label;             // The label, not broken into lines  protected int margin_width;         // Left and right margins  protected int margin_height;        // Top and bottom margins  protected int alignment;            // The alignment of the text.  public static final int LEFT = 0, CENTER = 1, RIGHT = 2; // alignment values  // Computed state values  protected int num_lines;            // The number of lines  protected String[] lines;           // The label, broken into lines  protected int[] line_widths;        // How wide each line is  protected int max_width;            // The width of the widest line  protected int line_height;          // Total height of the font  protected int line_ascent;          // Font height above baseline  protected boolean measured = false; // Have the lines been measured?  // Here are five versions of the constructor  public MultiLineLabel(String label, int margin_width,                        int margin_height, int alignment) {    this.label = label;                 // Remember all the properties    this.margin_width = margin_width;    this.margin_height = margin_height;    this.alignment = alignment;    newLabel();                         // Break the label up into lines  }  public MultiLineLabel(String label, int margin_width, int margin_height) {    this(label, margin_width, margin_height, LEFT);  }  public MultiLineLabel(String label, int alignment) {    this(label, 10, 10, alignment);  }  public MultiLineLabel(String label) { this(label, 10, 10, LEFT); }  public MultiLineLabel() { this(""); }  // Methods to set and query the various attributes of the component  // Note that some query methods are inherited from the superclass.  public void setLabel(String label) {    this.label = label;    newLabel();               // Break the label into lines    measured = false;         // Note that we need to measure lines    repaint();                // Request a redraw  }  public void setFont(Font f) {    super.setFont(f);         // tell our superclass about the new font    measured = false;         // Note that we need to remeasure lines    repaint();                // Request a redraw  }  public void setForeground(Color c) {    super.setForeground(c);   // tell our superclass about the new color    repaint();                // Request a redraw (size is unchanged)  }  public void setAlignment(int a) { alignment = a; repaint(); }  public void setMarginWidth(int mw) { margin_width = mw; repaint(); }  public void setMarginHeight(int mh) { margin_height = mh; repaint(); }  public String getLabel() { return label; }  public int getAlignment() { return alignment; }  public int getMarginWidth() { return margin_width; }  public int getMarginHeight() { return margin_height; }  /**   * This method is called by a layout manager when it wants to   * know how big we'd like to be.  In Java 1.1, getPreferredSize() is   * the preferred version of this method.  We use this deprecated version   * so that this component can interoperate with 1.0 components.   */  public Dimension preferredSize() {    if (!measured) measure();    return new Dimension(max_width + 2*margin_width,                         num_lines * line_height + 2*margin_height);  }  /**   * This method is called when the layout manager wants to know   * the bare minimum amount of space we need to get by.   * For Java 1.1, we'd use getMinimumSize().   */  public Dimension minimumSize() { return preferredSize(); }  /**   * This method draws the label (same method that applets use).   * Note that it handles the margins and the alignment, but that   * it doesn't have to worry about the color or font--the superclass   * takes care of setting those in the Graphics object we're passed.   */  public void paint(Graphics g) {    int x, y;    Dimension size = this.size();  // use getSize() in Java 1.1    if (!measured) measure();    y = line_ascent + (size.height - num_lines * line_height)/2;    for(int i = 0; i < num_lines; i++, y += line_height) {      switch(alignment) {      default:      case LEFT:    x = margin_width; break;      case CENTER:  x = (size.width - line_widths[i])/2; break;      case RIGHT:   x = size.width - margin_width - line_widths[i]; break;      }      g.drawString(lines[i], x, y);    }  }  /** This internal method breaks a specified label up into an array of lines.   *  It uses the StringTokenizer utility class. */  protected synchronized void newLabel() {    StringTokenizer t = new StringTokenizer(label, "\n");    num_lines = t.countTokens();    lines = new String[num_lines];    line_widths = new int[num_lines];    for(int i = 0; i < num_lines; i++) lines[i] = t.nextToken();  }  /** This internal method figures out how the font is, and how wide each   *  line of the label is, and how wide the widest line is. */  protected synchronized void measure() {    FontMetrics fm = this.getToolkit().getFontMetrics(this.getFont());    line_height = fm.getHeight();    line_ascent = fm.getAscent();    max_width = 0;    for(int i = 0; i < num_lines; i++) {      line_widths[i] = fm.stringWidth(lines[i]);      if (line_widths[i] > max_width) max_width = line_widths[i];    }    measured = true;  }}	//	MultiLineLabel//////////		Code for the parser////////		// Mathematical expressions.// Copyright 1996 by Darius Bacon; see the file COPYING.// 14May96: added constant folding// 07JUL1999 - version 1.0 - C. Pheatt// 05AUG2000 - Mike May, S.J.//				add in SEC, CSC. ToDEG, TORADpackage expr;/** * A mathematical expression, built out of literal numbers, variables, * arithmetic operators, and elementary functions.  The operator names * are from java.lang.Math. */public abstract class Expr {  /** @return the value given the current variable values */  public abstract double value ();  /** Binary operator. */  public static final int ADD = 0;    /** Binary operator. */  public static final int SUB = 1;  /** Binary operator. */  public static final int MUL = 2;  /** Binary operator. */  public static final int DIV = 3;  /** Binary operator. */  public static final int POW = 4;  /** Binary operator. */  public static final int MOD = 5;  /** Binary operator. */  public static final int LTH = 6;  /** Binary operator. */  public static final int LEQ = 7;  /** Binary operator. */  public static final int GTH = 8;  /** Binary operator. */  public static final int GEQ = 9;  /** Binary operator. */  public static final int EQU = 10;  /** Binary operator. */  public static final int NEQ = 11;  /** Binary operator. */  public static final int AND = 12;  /** Binary operator. */  public static final int ORR = 13;  /** Unary operator. */        public static final int ABS   = 100;  /** Unary operator. */        public static final int ACOS  = 101;  /** Unary operator. */        public static final int ASIN  = 102;  /** Unary operator. */        public static final int ATAN  = 103;  /** Unary operator. */        public static final int CEIL  = 104;  /** Unary operator. */        public static final int COS   = 105;  /** Unary operator. */        public static final int EXP   = 106;  /** Unary operator. */        public static final int FLOOR = 107;  /** Unary operator. */        public static final int LOG   = 108;  /** Unary minus operator. */  public static final int NEG   = 109;  /** Unary operator. */        public static final int ROUND = 110;  /** Unary operator. */        public static final int SIN   = 111;  /** Unary operator. */        public static final int SQRT  = 112;  /** Unary operator. */        public static final int TAN   = 113;  /** Unary operator. */        public static final int LOG10 = 114;  /** Unary operator. */        public static final int SEC   = 115;  /** Unary operator. */        public static final int CSC   = 116;  /** Unary operator. */        public static final int TODEG = 117;  /** Unary operator. */        public static final int TORAD = 118;  /** Unary operator. */     	public static final int FACT  = 119;    public static Expr make_literal (double v) {     return new Literal (v);   }  public static Expr make_var_ref (Variable var) {    return new Var_ref (var);  }  /**    * @param rator unary operator   * @param rand operand   */  public static Expr make_app1 (int rator, Expr rand) {    Expr app = new App1 (rator, rand);    return rand instanceof Literal ? new Literal (app.value ()) : app;  }  /**    * @param rator binary operator   * @param rand0 left operand   * @param rand1 right operand   */  public static Expr make_app2 (int rator, Expr rand0, Expr rand1) {    Expr app = new App2 (rator, rand0, rand1);    return rand0 instanceof Literal && rand1 instanceof Literal	     ? new Literal (app.value ()) 	     : app;  }}	//	Expr// These classes are all private to this module so that I can get rid// of them later.  For applets you want to use as few classes as// possible to avoid http connections at load time; it'd be profitable// to replace all these subtypes with bytecodes for a stack machine,// or perhaps a type that's the union of all of them (see class Node// in java/demo/SpreadSheet/SpreadSheet.java).class Literal extends Expr {  double v;  Literal (double _v) { v = _v; }  public double value () { return v; }}	//	Literalclass Var_ref extends Expr {  Variable var;  Var_ref (Variable _var) { var = _var; }  public double value () { return var.value (); }}	//	Var_refclass App1 extends Expr {  int rator;  Expr rand;  App1 (int _rator, Expr _rand) { rator = _rator; rand = _rand;  }  public double value () {    double arg = rand.value ();    switch (rator) {    case ABS:   return Math.abs (arg);    case ACOS:  return Math.acos (arg);    case ASIN:  return Math.asin (arg);    case ATAN:  return Math.atan (arg);    case CEIL:  return Math.ceil (arg);    case COS:   return Math.cos (arg);    case EXP:   return Math.exp (arg);    case FACT:  return MiscFunctions.fact (arg);    case FLOOR: return Math.floor (arg);    case LOG:   return Math.log (arg);    case LOG10: return Math.log (arg) * 0.434294481903251827651128918916;    case NEG:   return -arg;    case ROUND: return Math.round (arg);    case SIN:   return Math.sin (arg);    case SQRT:  return Math.sqrt (arg);    case TAN:   return Math.tan (arg);    case SEC:   return 1/Math.cos (arg);    case CSC:   return 1/Math.sin (arg);    case TODEG: return 180*(arg)/(3.141582653589793);    case TORAD: return (Math.PI)*(arg)/180;    default: throw new RuntimeException ("BUG: bad rator");    }  }}	//	App1class App2 extends Expr {  int rator;  Expr rand0, rand1;  App2 (int _rator, Expr _rand0, Expr _rand1) {     rator = _rator; rand0 = _rand0; rand1 = _rand1;  }  public double value () {    double arg0 = rand0.value ();    double arg1 = rand1.value ();    switch (rator) {    case ADD:  return arg0 + arg1;    case SUB:  return arg0 - arg1;    case MUL:  return arg0 * arg1;    case DIV:  return arg0 / arg1;   // check for division by 0?    case POW:  return Math.pow (arg0, arg1);    case MOD:  return arg0 % arg1;    case LTH:  if(arg0 < arg1) return 1; else return 0;    case LEQ:  if(arg0 <= arg1) return 1; else return 0;    case GTH:  if(arg0 > arg1) return 1; else return 0;    case GEQ:  if(arg0 >= arg1) return 1; else return 0;    case EQU:  if(arg0 == arg1) return 1; else return 0;    case NEQ:  if(arg0 != arg1) return 1; else return 0;    case AND:  if((arg0 != 0) && (arg1 != 0)) return 1; else return 0;    case ORR:  if((arg0 != 0) || (arg1 != 0)) return 1; else return 0;    default: throw new RuntimeException ("BUG: bad rator");    }  }}	//	App2//	End package Expr// Operator-precedence parser.// Copyright 1996 by Darius Bacon; see the file COPYING.// 14May96: bugfix. //	StreamTokenizer treated '-<number>' as a numeric token, not a minus//	operator followed by a number.  Fix: make '-' an ordinaryChar.// 12May97: Changed the precedence of unary minus to be lower than //      multiplication, so -y^2 is like -(y^2), not (-y)^2.// 07JUL1999 - version 1.0 - C. Pheatt// 05AUG2000 - Mike May, S.J.//				add in sec, csc, toDegrees, toRadians, lnpackage expr;import java.io.*;/**   Parses strings representing mathematical formulas with variables.  The following operators, in descending order of precedence, are  defined:  <UL>  <LI>^ (raise to a power)  <LI>* /  <LI>Unary minus (-x)  <LI>+ -  </UL>  ^ associates right-to-left; other operators associate left-to-right.  <P>These functions are defined:     abs, acos, asin, atan,     ceil, cos, exp, floor,     log, round, sin, sqrt,     tan.  Each requires one argument enclosed in parentheses.  <P>Whitespace outside identifiers is ignored.  <P>The syntax-error messages aren't very informative, unfortunately.  IWBNI it indicated where in the input string the parse failed, but   that'd be kind of a pain since our scanner is a StreamTokenizer.  A  hook for that info should've been built into StreamTokenizer.  <P>Examples:  <UL>  <LI>42  <LI>2-3  <LI>cos(x^2) + sin(x^2)  <UL> */public class Parser {  static StreamTokenizer tokens;  public static Expr parse (String input) throws Syntax_error {    tokens = new StreamTokenizer (new StringReader (input));    tokens.ordinaryChar ('/');    tokens.ordinaryChar ('-');    tokens.ordinaryChar ('%');    tokens.ordinaryChar ('>');    tokens.ordinaryChar ('<');    tokens.ordinaryChar ('=');    tokens.ordinaryChar ('!');    tokens.ordinaryChar ('&');    tokens.ordinaryChar ('|');    next ();    Expr expr = parse_expr (0);    if (tokens.ttype != StreamTokenizer.TT_EOF)      throw new Syntax_error ("Incomplete expression: " + input);    return expr;  }  static void next () {    try { tokens.nextToken (); }    catch (IOException e) { throw new RuntimeException ("I/O error: " + e); }  }  static void push () {     tokens.pushBack();   }  static void expect (int ttype) throws Syntax_error {    if (tokens.ttype != ttype)      throw new Syntax_error ("'" + (char) ttype + "' expected");    next ();  }  static Expr parse_expr (int precedence) throws Syntax_error {    Expr expr = parse_factor ();  loop: for (;;) {      int l, r, rator;         // The operator precedence table.      // l = left precedence, r = right precedence, rator = operator.      // Higher precedence values mean tighter binding of arguments.      // To associate left-to-right, let r = l+1;      // to associate right-to-left, let r = l.      switch (tokens.ttype) {      case '|':         l = 2; r = 3; rator = Expr.ORR;        next();        if(tokens.ttype != '|') push();        break;      case '&':         l = 4; r = 5; rator = Expr.AND;         next();        if(tokens.ttype != '&') push();        break;      case '=':         l = 6; r = 7; rator = Expr.EQU;         next();        if(tokens.ttype != '=') push();        break;              case '!':         l = 6; r = 7; rator = Expr.NEQ;         next();        if(tokens.ttype != '=') push();        break;            case '<':        l = 8; r = 9;        next();        if(tokens.ttype != '=')  {            push();            rator = Expr.LTH;         }        else {            rator = Expr.LEQ;         }            break;              case '>':        l = 8; r = 9;         next();        if(tokens.ttype != '=')  {            push();            rator = Expr.GTH;         }        else {            rator = Expr.GEQ;         }            break;            case '+': l = 10; r = 11; rator = Expr.ADD; break;      case '-': l = 10; r = 11; rator = Expr.SUB; break;	      case '%': l = 20; r = 21; rator = Expr.MOD; break;      case '*': l = 20; r = 21; rator = Expr.MUL; break;      case '/': l = 20; r = 21; rator = Expr.DIV; break;	      case '^': l = 30; r = 30; rator = Expr.POW; break; 	      default: break loop;      }      if (l < precedence)	break loop;      next ();      expr = Expr.make_app2 (rator, expr, parse_expr (r));    }    return expr;  }  static String[] procs = {    "abs", "acos","arccos", "asin",    "arcsin", "atan", "arctan",    "ceil", "cos", "exp", "floor",     "log", "ln", "round", "sin", "sqrt",     "tan", "log10", "sec", "csc",    "toDegrees", "toRadians", "fact"  };  static int[] rators = {    Expr.ABS, Expr.ACOS, Expr.ACOS, Expr.ASIN,    Expr.ASIN, Expr.ATAN, Expr.ATAN,     Expr.CEIL, Expr.COS, Expr.EXP, Expr.FLOOR,    Expr.LOG, Expr.LOG, Expr.ROUND, Expr.SIN, Expr.SQRT,     Expr.TAN , Expr.LOG10, Expr.SEC, Expr.CSC,    Expr.TODEG, Expr.TORAD, Expr.FACT  };	  static Expr parse_factor () throws Syntax_error {    switch (tokens.ttype) {    case StreamTokenizer.TT_NUMBER: {      Expr lit = Expr.make_literal (tokens.nval);      next ();      return lit;    }    case StreamTokenizer.TT_WORD: {      for (int i = 0; i < procs.length; ++i)	if (procs [i].equals (tokens.sval)) {	  next ();	  expect ('(');	  Expr rand = parse_expr (0);	  expect (')');	  return Expr.make_app1 (rators [i], rand);	}      Expr var = Expr.make_var_ref (Variable.make (tokens.sval));      next ();      return var;    }    case '(': {      next ();      Expr enclosed = parse_expr (0);      expect (')');      return enclosed;    }    case '-':       next ();      return Expr.make_app1 (Expr.NEG, parse_expr (15));    default:      throw new Syntax_error ("Expected a factor");    }  }}// Syntax-error exception.// Copyright 1996 by Darius Bacon; see the file COPYING.package expr;public class Syntax_error extends Exception {  public Syntax_error (String complaint) { super (complaint); }}// Put the expression evaluator through its paces.// Sample usage:// $ java expr.Test '3.14159 * x^2' 0 4 1// 0// 3.14159// 12.5664// 28.2743// 50.2654//// $ java expr.Test 'sin (pi/4 * x)' 0 4 1// 0// 0.707107// 1// 0.707107// 1.22461e-16//package expr;import expr.*;public class Test {  public static void main (String[] args) {    Expr expr;   	try   	{   		expr = Parser.parse (args [0]);   	}	catch (Syntax_error e)	{		System.err.println ("Syntax error: " + e);		return;	}    double low  = Double.valueOf (args [1]).doubleValue ();    double high = Double.valueOf (args [2]).doubleValue ();    double step = Double.valueOf (args [3]).doubleValue ();          Variable x = Variable.make ("x");    Variable.make ("pi").set_value (Math.PI);    for (double xval = low; xval <= high; xval += step) {      x.set_value (xval);      System.out.println (expr.value ());    }  }}/*	Trivial library - 4/96 PNL*/public class TrivialClass {		public TrivialClass() {	}}// Variables associate values with names.// Copyright 1996 by Darius Bacon; see the file COPYING.package expr;import java.util.Hashtable;/** * Variables associate values with names. */public class Variable {  static Hashtable variables = new Hashtable ();  /**   * Return <EM>the</EM> variable named `_name'.     * make (s1) == make (s2) iff s1.equals (s2).   */  static public Variable make (String _name) {    Variable result = (Variable) variables.get (_name);    if (result == null)      variables.put (_name, result = new Variable (_name));    return result;  }  String name;  double val;  public Variable (String _name) { name = _name; val = 5; }  public String toString () { return name; }  public double value () { return val; }  public void set_value (double _val) { val = _val; }}	//	Variable/*  Copying file for expr packageCopyright 1996 by Darius Bacon.Permission is granted to anyone to use this software for anypurpose on any computer system, and to redistribute it freely,subject to the following restrictions:1. The author is not responsible for the consequences of use of   this software, no matter how awful, even if they arise from    defects in it.2. The origin of this software must not be misrepresented, either   by explicit claim or by omission.3. Altered versions must be plainly marked as such, and must not   be misrepresented as being the original software.   */   //	MIO = My Input Output//	It is a collection of methods for cleaning up input and output.//	Mike May, S.J.//	maymk@slu.edu//	August, 2001/*	Current method list *	public static int intFromTextField(TextField tf)  *	public static double doubleFromTextField(TextField tf)  *	public static String doubleToStringDecPrecision(double d, int decfigs)  *	public static String doubleToStringNoE(TextField tf)  *	public static String doubleToStringSigFigures(double d, int sigfigs) * *	This version tries to interpret doubles first in Java format, then as *	an NFunction.  Java format allows sx.xxxxxxEsxxx while NFunctions *	allow usual mathematical constructions. */package MIO;import	java.awt.*;import	ZFunction;public  class Mio {		public Mio() {}/** This is a utility routine to retrieve an integer from a text field. */	public static int intFromTextField(TextField tf) 	{		String  string;		int     value;				string = tf.getText();		try {		   value = Integer.parseInt(string);		} catch (Exception e) {       System.out.println("Warning, noninteger read for integer value.");       System.out.println("The variable has be set to 0.");		   value = 0;		}		   		return value;	}	//	intFromTextField	public static double doubleFromTextField(TextField tf) 	{		ZFunction	func = new ZFunction();   				String		string;		double		value;				string = tf.getText();		try {			value = Double.valueOf(string).doubleValue();		} catch (Exception e) {		try {		func.parse(string);			value = func.value(1);		} catch (Exception se) {       System.out.println("Warning, nondouble read for double value.");       System.out.println("The variable has be set to 0.0.");		   value = 0.0;		}}		return value;	}	//	doubleFromTextField	//	This procedure is intended to turn a double into a a string with a 	// specified decimal precision.	public static String doubleToStringDecPrecision(double d, int decfigs) 	{	     if (d == 0) return "0.0";	     else return String.valueOf((Math.round(d*(Math.pow(10,decfigs))))/                  (Math.pow(10,decfigs)));	}	//	doubleToStringDecPrecision	//	This procedure is intended to turn a double into a string with the added	//	provision being that the string not use E notation.	//	The point is if the string is then to be used in a an expression by a parser.	//	The output format is either (sxxx.xxx) or (sx.xxxx)*10^(sxxx).	public static String doubleToStringNoE(double d) 	{		String s1 = Double.toString(d);		int loc = s1.indexOf("E");		int len = s1.length();			System.out.println("E at " + loc + " length is " + len);		if (loc == -1) return s1;		else return "(" + s1.substring(0,loc) +")*10^(" + s1.substring(loc+1,len) + ")";	}	//	doubleToStringNoE	//	This procedure is intended to turn a double into a string with a specified	//	number of significant figures.  We need to divide into cases on whether	//	s1 is already in scientific notation.	public static String doubleToStringSigFigures(double d, int sigfigs)	{		String s1 = Double.toString(d);		int len = s1.length();		int loc = s1.indexOf("E");		int posdot = s1.indexOf(".");		int pos;		if (sigfigs < 1) return s1;		if (loc != -1)	// There is an E in s1		{			pos = Math.min(posdot+sigfigs, loc);				return  s1.substring(0,pos) +"E" + s1.substring(loc+1,len);		}		else	// no E in the string representation s1		{			pos = sigfigs + 1;			if (s1.indexOf("-") == 0) pos += 1;			if (posdot <= pos)	//	Need to keep figures right of decimal			{					int dotMove = (Double.toString(d*1000.0).indexOf(".") - posdot);				int leadZeroes = 3 - dotMove;	// count leading zeroes and adjust				if (leadZeroes > 0) pos += leadZeroes;				pos = Math.min(pos, len);				return s1.substring(0, pos);			}			int numZeroes = posdot - pos;			String s2 = s1.substring(0, pos);			for (int i = 0; i< numZeroes; i++) s2 = s2 + "0";			return s2 + ".0";		}	}	//	doubleToStringSigFigures}	//	class MIO   
