 |
Example - Graph
* The "\" symbol has been used at the end of lines to indicate that the line was too long for the display and has been
wrapped to the line below in order to fit within the width of the web page. These lines would need to be joined in the normal
program editor.
I. Introduction
This program will plot graphs of any explicit function y(x) (with a few exceptions – see ‘Mathematics involved') and calculate the gradient, the area under the graph, and find roots (where the line crosses the x -axis) via the Newton-Raphson method. It makes use, therefore, of the new Integrate and Differentiate methods.

II. Mathematics Involved
It should be noted that the program cannot plot non-analytic functions such as sin(1/x) at the origin, or log(x) for negative x . In these cases a readjustment of the axes is required.
The Newton-Raphson method is a method for finding roots of an equation numerically. It approximates the root at x by calculating where a tangent to the curve at point x0 would cross the y-axis, then repeating the process at this point ( x1 ) and so on. It is not infallible, but almost always works.
The iterative formula is:

III. How The Program Works
1) The DoneForm() Procedure
When the formula box is clicked and the formula entered, the following procedure is called to convert the formula into a compatible format, by inserting % signs after any occurrences of “x” which were not part of the EXP function.
SUB DoneForm()
Superbase.StatusText = "Checking formula"
tempform$ = Superbase.Dialogs.Formula.formbox.Text
i%% = 1
WHILE i%% <= LEN (tempform$)
IF MID$ (tempform$,i%%,1) = "x" OR MID$ (tempform$,i%%,1) = "X" THEN
'unless the "x" is part of "exp"
IF (i%% = 1) OR ( MID$ (tempform$,i%% - 1,1) <> "e" AND MID$ \ (tempform$,i%% - 1,1) <> "E") THEN
'check it has a % after it
IF MID$ (tempform$,i%% + 1,1) <> "%" THEN
'put one in
tempform2$ = MID$ (tempform$,i%% + 1)'the end of the string
tempform3$ = LEFT$ (tempform$,i%%)'the beginning of the string
tempform$ = tempform3$ + "%" + tempform2$
END IF
END IF
END IF
i%% = i%% + 1
WEND
'test syntax
Superbase.ErrorTrapLabel = "formerr"
x% = 10.265446546448'an arbitrary test value of x
DIM y%
EXECUTE ("y%=" + tempform$)
'if there is an error here it is probably because of a mistyping
'there are unlikely to be any singularities at this arbitrary value
formula$ = tempform$
Superbase.Dialogs.Formula.SetActive(0)
CALL drawgraph()
END SUB
2) The drawgraph() Procedure
The line is then drawn, starting at the minimum value of x specified, and then advancing 2 pixels each time.
SUB drawgraph()
RangeError%% = 0
Superbase.StatusText = "Drawing graph..."
Superbase.ErrorTrapLabel = "rangeerr"
'if there is an error at this stage, then, since the syntax of the \ formula is OK, it must be the
'range that is causing the problems (eg sqr of a negative number)
GraphThere%% = - 1
tempform$ = formula$
CALL gclear()
formula$ = tempform$
DIM j%%
x% = xmin%:oldx% = x%
currentx% = x%
EXECUTE ("y%=" + formula$)
oldy% = y%
GraphThere%% = - 1
i%% = 1
WHILE x% < xmax% AND RangeError%% = 0
currentx% = x%
y% = Superbase.Summation(formula$,"j%%",1,1)
IF y% <= ymax% AND y% >= ymin% THEN
CALL DrawLine(oldx%,oldy%,x%,y%,i%%)
END IF
oldx% = x%
oldy% = y%
x% = x% + 2 / xfact%:i%% = i%% + 1
WEND
G.formula.caption = "y = " + formula$
G.Refresh()
END SUB
SUB DrawLine(oldx%,oldy%,x%,y%,i%%)
DIM x1%%,y1%%,x2%%,y2%%
LineName$ = "line" + STR$ (i%%)
SET fc = G.Add(LineName$,"Line")
x1%% = 50 + (oldx% - xmin%) * xfact%:y1%% = 450 - (oldy% - ymin%) *\
yfact%
x2%% = 50 + (x% - xmin%) * xfact%:y2%% = 450 - (y% - ymin%) * yfact%
fc.Move(x1%%,y1%%,x2%%,y2%%)
fc.ForeColor = 2
END SUB

3) The integrate() Procedure
When the Area button is clicked, the program waits for input from the user – a left click on the graph to determine the lower limit of integration and a right click to determine the upper limit. Alternatively, the limits can be entered directly in the text boxes if preferred. Then the integration is performed.
WHILE (G.lbox.Text = "") OR (G.rbox.Text = "") AND NOT done%%
Process()
IF G.tag <> "" THEN
done%% = - 1
ELSE
mx%% = Window.MouseX:my%% = Window.MouseY
onrect%% = IF ((mx%% >= 50) AND (mx%% <= 450) AND (my%% >= 50) AND \ (my%% <= 450), - 1,0)
IF onrect%% = - 1 THEN
x% = (Window.MouseX - 50) / xfact% + xmin%
y% = (450 - Window.MouseY) / yfact% + ymin%
pos$ = "(" + STR$ (x%) + "," + STR$ (y%) + ")"
IF Superbase.StatusText <> pos$ THEN Superbase.StatusText = pos$
IF MouseLButton = - 1 THEN CALL lclick()
IF MouseRButton = - 1 THEN CALL rclick()
END IF
END IF
WEND
IF NOT done%% THEN
Superbase.StatusText = "Integrating"
LLimit% = VAL (G.lbox.Text):ULimit% = VAL (G.rbox.Text)
IF formula$ = "" THEN
G.resbox.Text = "no formula!"
ELSE
G.resbox.Text = STR$ (Superbase.Integrate(formula$,"x%",LLimit%,\ ULimit%,0.0001))
END IF
G.resbox.Visible = - 1
G.reslab.Visible = - 1
G.OKbtn.Visible = - 1
G.OKbtn.Enabled = - 1
G.Refresh()
Superbase.StatusText = "Click OK"
WHILE G.OKbtn.Enabled = - 1
Process()
WEND
END IF
END SUB
4) The diff() Procedure
The procedure followed when the Gradient button is clicked is similar, but this time only a left click is needed.
WHILE (G.lbox.Text = "") OR (G.rbox.Text = "") AND NOT done%%
Process()
IF G.tag <> "" THEN
done%% = - 1
ELSE
mx%% = Window.MouseX:my%% = Window.MouseY
onrect%% = IF ((mx%% >= 50) AND (mx%% <= 450) AND (my%% >= 50) AND \ (my%% <= 450), - 1,0)
IF onrect%% = - 1 THEN
x% = (Window.MouseX - 50) / xfact% + xmin%
y% = (450 - Window.MouseY) / yfact% + ymin%
pos$ = "(" + STR$ (x%) + "," + STR$ (y%) + ")"
IF Superbase.StatusText <> pos$ THEN Superbase.StatusText = pos$
IF MouseLButton = - 1 THEN CALL lclick()
IF MouseRButton = - 1 THEN CALL rclick()
END IF
END IF
WEND
IF NOT done%% THEN
Superbase.StatusText = "Integrating"
LLimit% = VAL (G.lbox.Text):ULimit% = VAL (G.rbox.Text)
IF formula$ = "" THEN
G.resbox.Text = "no formula!"
ELSE
G.resbox.Text = STR$ (Superbase.Integrate(formula$,"x%",LLimit%, \ ULimit%,0.0001))
END IF
G.resbox.Visible = - 1
G.reslab.Visible = - 1
G.OKbtn.Visible = - 1
G.OKbtn.Enabled = - 1
G.Refresh()
Superbase.StatusText = "Click OK"
WHILE G.OKbtn.Enabled = - 1
Process()
WEND
END IF
END SUB
5) The nr() Procedure
When the Find Root button is clicked, the program waits for the user to select a starting value from which to look for the root. Only a rough approximation is needed, but if the value of a particular root is desired, it is sensible to start nearer that root rather than another. Then the Newton-Raphson algorithm starts:
Superbase.StatusText = "Finding root"
xval% = VAL (G.lbox.Text)
DIM numits%%
numits%% = 0
WHILE ( ABS (difference%) > epsilon%) AND (numits%% < 100)
x% = xval%
EXECUTE ("fx%=" + formula$)
fxdash% = Superbase.Differentiate(formula$,"x%",xval%,0.0001)
oldxval% = xval%
xval% = xval% - fx% / fxdash%
numits%% = numits%% + 1
difference% = xval% - oldxval%
WEND
IF numits%% < 100 THEN
G.resbox.Text = STR$ (xval%,"999.0000000")
G.resbox.Visible = - 1
G.reslab.Visible = - 1
G.itslab.Caption = "(" + LTRIM$ ( STR$ (numits%%,"999")) + \ " iterations)
G.itslab.Visible = - 1
ELSE
G.resbox.Text = "diverges"
END IF
G.OKbtn.Visible = - 1
G.OKbtn.Enabled = - 1
G.Refresh()
Superbase.StatusText = "Click OK"
WHILE G.OKbtn.Enabled = - 1
Process()
WEND

|