ITERCODE.HTM
SOURCE CODE

Return to LeftSide.

This is the source code which is discussed in the ITERATION PAPER.
It is written for Microsoft's QB45 syntax and can be used as is within that language environment.
Follow these steps,
1. Save this webpage using your browser's functions.
2. Use a plain ASCII text editor, WINDOW's Notepad or DOS Editor, and delete the HTML code lines along with these instructions.
There are three lines at the end of the file which should also be deleted.
3. Save the modified file as "ITERCODE.BAS", or other name of your choice, in your QB45 directory or whatever other basic language environment you use.

' Delete the above lines and this one.
' RE-SAVE "ITERCODE.BAS"
' Last STORED on Jul 21, 97 at  3:30
'                   Copyright by Jerry Hughes 1997
' Modification history:
' 1997
' Mar 24:  This program accompanies the ITERATION paper which describes the
' iteration principles used in this code.
'          The main program, including some GOSUB routines, contains code
' to aid in data entry and change as well as solution results.
'          The structure of the code employs FUNCTION definitions where the
' user is allowed to define application equations and code.
'          The syntax of this code is for MicroSoft's QBASIC 4.5 and use
' of their QBASIC software is required to use this code as is.  Otherwise,
' translate the code into your basic's syntax or programming language.
'
'          A full and complete DISCLAIMER is declared by the composer.
'          Use at your own risk; verify results and applicablity.
'

DEFDBL X-Z
DECLARE FUNCTION FUNC1# (x, D$)
DECLARE FUNCTION FUNC2# (x, D$)
DECLARE FUNCTION FUNC3# (x, D$)
DECLARE FUNCTION FUNC4# (x, D$)
DECLARE FUNCTION FUNC5# (x, D$)
DECLARE FUNCTION LGT (x)

DIM xOFy(10), Y1eqY2atX(10), y1atx(10)
DIM LYmn(10), LXmn(10), LYmx(10), LXmx(10), FPy(10), FPx(10)

It0$ = "0": It1$ = "1": It2$ = "2": It3$ = "3": It4$ = "4": It5$ = "5": It6$ = "6"
It7$ = "7": It8$ = "8": It9$ = "9": ItA$ = "A": ItB$ = "B": ItC$ = "C"
ItD$ = "D": ItE$ = "E": ItF$ = "F": ItG$ = "G": ItH$ = "H": ItI$ = "I"
ItJ$ = "J": ItK$ = "K": ItL$ = "L": ItM$ = "M": ItN$ = "N": ItO$ = "O"

Ast$ = "*": Null$ = "": No$ = "No ": Yes$ = "Yes"
NotDone$ = "Not Done": Done$ = "Done"
Anal$(1) = "Inverse   ": Anal$(2) = "Mx/Mn/FP  ": Anal$(3) = "Intersect "
AnaDone$ = NotDone$

Fmt00$ = "##.####^^^^"
Fmt01$ = "& ##.####^^^^"

FOR I = 1 TO 79: Line$ = Line$ + " ": NEXT I
BlkHL$ = MID$(Line$, 1, 39)

Blu = 1: Gre = 2: Cya = 3: Red = 4: Mag = 5: Bro = 6: Whi = 7: Gra = 8
Bblu = 9: Bgre = 10: Bcya = 11: Bred = 12: Bmag = 13: Byel = 14: Bgra = 15
LColor = 9

Mx = 21: Ip = 22: BotLin = 23  ' Note/message, Prompt, Bottom lines

PI = ATN(1) * 4
Rpd = PI / 180

' **********************************
' Default values for input variables
' Define these values for intitial startup
' **********************************

FeqMax = 5                          ' Maximum # of FUNCTIONs defined
Feq0 = 2: x = .000125: Feq = Feq0   ' Function to analize
GOSUB Selfunc: FDesc0$ = FDesc$     ' Function description
DoMin = 0: DoMax = 7                ' Domain
Npts = 100                          ' Number of increments in domain
Anal = 1                            ' Type of analysis, inverse
YofX = 10#                          ' Given function value
Tol# = .000001                      ' Tolerance
AborTime = 90                       ' Time out limit during iterations
Feq1 = 2: x = .000125: Feq = Feq1   ' First function for intersection
GOSUB Selfunc: FDesc1$ = FDesc$     ' and its description
Feq2 = 3: x = .000125: Feq = Feq2   ' Second function for intersection
GOSUB Selfunc: FDesc2$ = FDesc$     ' and its description
Progress = 1                        ' Show progress status
ProgStat$ = "On"

' ************************************
' ************************************

GOTO Options

BlkMxL: LOCATE Mx, 1: PRINT Line$: PRINT Line$: LOCATE Mx, 1: RETURN

PauseLine: GOSUB BlkMxL: PRINT "Press any key to continue."
   DO: LOOP UNTIL INKEY$ <> Null$: GOSUB BlkMxL
   RETURN

GetKey: Digit = 0: DO: C$ = INKEY$: LOOP UNTIL C$ <> Null$
   IF ASC(C$) = 13 THEN RETURN
   IF ASC(C$) > 47 AND ASC(C$) < 58 THEN Digit = VAL(C$)
   Key$ = UCASE$(C$)
   RETURN

GetNum2: DOK = 1: GOSUB BlkMxL: PRINT Pmt$; : LINE INPUT a$
   IF a$ = Null$ THEN RETURN
   FOR Ign = 1 TO LEN(a$)
      B$ = MID$(a$, Ign, 1)
      IF ASC(B$) < 46 OR ASC(B$) > 57 THEN DOK = 0
      IF ASC(B$) = 47 THEN DOK = 0
   NEXT Ign
   IF DOK = 0 THEN BEEP: GOTO GetNum2
   jwh = VAL(a$)
   xjwh = VAL(a$)  ' For double precision values
   RETURN

ResltScr: IF AnaDone$ = NotDone$ THEN RETURN
IF Abort$ <> Null$ THEN LOCATE BotLin, 1: PRINT Abort$
Col = 40: Row = 2
IF Anal = 1 THEN
  LOCATE Row, Col: PRINT USING Fmt01$; "f(x)  = "; YofX
  Row = Row + 1: LOCATE Row, Col: PRINT "for x ="
  FOR I = 1 TO Sol: Row = Row + 1: LOCATE Row, Col: PRINT USING Fmt00$; xOFy(I): NEXT I
END IF
IF Anal = 2 THEN
   IF (Sol1 + Sol2 + Sol3) > 15 THEN RETURN
   LOCATE Row, Col: PRINT "Inflection for x ="
   FOR I = 1 TO Sol3: Row = Row + 1: LOCATE Row, Col: PRINT USING Fmt00$; FPx(I): NEXT I
   Row = Row + 1: LOCATE Row, Col: PRINT "Local Max, for x ="
   FOR I = 1 TO Sol2: Row = Row + 1: LOCATE Row, Col: PRINT USING Fmt00$; LXmx(I): NEXT I
   Row = Row + 1: LOCATE Row, Col: PRINT "Local Min, for x ="
   FOR I = 1 TO Sol1: Row = Row + 1: LOCATE Row, Col: PRINT USING Fmt00$; LXmn(I): NEXT I
END IF
IF Anal = 3 THEN
  LOCATE Row, Col: PRINT "f1(x) = f2(x)"
  Row = Row + 1: LOCATE Row, Col: PRINT "for x ="
  FOR I = 1 TO Sol: Row = Row + 1: LOCATE Row, Col: PRINT USING Fmt00$; Y1eqY2atX(I): NEXT I
END IF
RETURN

' *****************
' MAIN OPTIONS MENU
' *****************

' 1. Function           Use to select function for INVERSE, INFLEC, MAX, MIN
'                       Toggles through the 5 DEF FUNC routines.
' 2. Domain minimum     Define minimum x value, start of iterations
' 3. Domain maximum     Define maximum x value, end of iterations
' 4. # of increments    Define number of increment between domain end points.
'                       Incremental value, xi, equals (DoMax - DoMin) / Npts.
' 5. Analysis type      Toggles through, INVERSE, MAX-MIN-INFLECTION, INTERSECTION.
' 6. Function value     Use to define given range value for INVERSE analysis.
' 7. Tolerance          Use to define tolerance for solutions, least significant digit.
' 8. Time limit (secs)  Use to define maximum amout of time spent in iteration loop.
' 9. Function 1         Use to select first function for INTERSECTION analysis.
' 0. Function 2         Use to select second function for INTERSECTION analysis.
' A. Do calculations    Use to start iteration analysis.
' B. Show progress      Toggles between display/no display of program progress. 
' C. End program        Terminates program.

MO4Scr:
PmtLine$ = "Main Options. "
COLOR Red, 0: PRINT "MAIN OPTIONS:": COLOR 7, 0
PRINT It1$; : PRINT " Function         "; : PRINT FDesc0$
PRINT It2$; : PRINT " Domain minimum   "; : PRINT USING Fmt00$; DoMin
PRINT It3$; : PRINT " Domain maximum   "; : PRINT USING Fmt00$; DoMax
PRINT It4$; : PRINT " # of increments  "; : PRINT USING Fmt00$; Npts
PRINT It5$; : PRINT " Analysis type    "; : PRINT Anal$(Anal)
PRINT It6$; : PRINT " Function value   "; : : PRINT USING Fmt00$; YofX
PRINT It7$; : PRINT " Tolerance        "; : : PRINT USING Fmt00$; Tol#
PRINT It8$; : PRINT " Time limit, secs "; : : PRINT AborTime
PRINT It9$; : PRINT " Function 1       "; : : PRINT FDesc1$
PRINT It0$; : PRINT " Function 2       "; : : PRINT FDesc2$
PRINT ItA$; : PRINT " Do calculations. "; AnaDone$
PRINT ItB$; : PRINT " Progress         "; ProgStat$
PRINT ItC$; : PRINT " End program      "
RETURN

' ************************
' END OF MAIN OPTIONS MENU
' ************************

Options:
MO4: CLS : GOSUB MO4Scr: GOSUB ResltScr
GOSUB BlkMxL
PRINT "Choose from "; : PRINT PmtLine$
GOSUB GetKey: MO4Key$ = Key$
IF Key$ <> ItF$ AND Key$ <> ItG$ AND Key$ <> ItH$ THEN AnaDone$ = NotDone$
SELECT CASE MO4Key$
CASE It1$
  Feq0 = Feq0 + 1: IF Feq0 > FeqMax THEN Feq0 = 1
  x = .0001235: Feq = Feq0: GOSUB Selfunc
  FDesc0$ = FDesc$
CASE It2$
  Pmt$ = "Enter minimum x value of domain. ": jwh = DoMin
  GOSUB GetNum2: DoMin = jwh
CASE It3$
  Pmt$ = "Enter maximum x value of domain. ": jwh = DoMax
  GOSUB GetNum2: DoMax = jwh
CASE It4$
  Pmt$ = "Enter number of domain increments. ": jwh = Npts
  GOSUB GetNum2: Npts = jwh
CASE It5$
  Anal = Anal + 1: IF Anal > 3 THEN Anal = 1
CASE It6$
  Pmt$ = "Enter function value. ": jwh = YofX
  GOSUB GetNum2: YofX = jwh
CASE It7$
  Pmt$ = "Enter the tolerance for solution. ": xjwh = Tol#
  GOSUB GetNum2: Tol# = xjwh
CASE It8$
  Pmt$ = "Enter abort analysis time limit, secs. ": jwh = AborTime
  GOSUB GetNum2: AborTime = jwh
CASE It9$
  Feq1 = Feq1 + 1: IF Feq1 > 5 THEN Feq1 = 1
  x = .0000123: Feq = Feq1: GOSUB Selfunc: FDesc1$ = FDesc$
CASE It0$
  Feq2 = Feq2 + 1: IF Feq2 > 5 THEN Feq2 = 1
  x = .0000123: Feq = Feq2: GOSUB Selfunc: FDesc2$ = FDesc$
CASE ItA$
  GOSUB Calculations
CASE ItB$
  Progress = -Progress
  IF Progress = 1 THEN ProgStat$ = "On" ELSE ProgStat$ = "Off"
CASE ItC$
  CLS : STOP
END SELECT
GOTO MO4

' End of MAIN PROGRAM: Data entry and change, results display.

Selfunc:  ' Select the required function according to Feq and evaluate f(x).
          ' Define FUNCTIONs using QBASIC software development.

IF Feq = 1 THEN y = FUNC1#(x, FDesc$)
IF Feq = 2 THEN y = FUNC2#(x, FDesc$)
IF Feq = 3 THEN y = FUNC3#(x, FDesc$)
IF Feq = 4 THEN y = FUNC4#(x, FDesc$)
IF Feq = 5 THEN y = FUNC5#(x, FDesc$)
RETURN

' Iteration procedures follow.

Calculations:
  GOSUB BlkMxL: PRINT "Press any key to abort."

' Use number of domain intervals to find initial x increment value.
  Pdx = (DoMax - DoMin) / Npts

Analysis:
GOSUB BlkMxL: PRINT "Press any key to abort."
SELECT CASE Anal
CASE 1 ' Inverse
Feq = Feq0                   ' Set select function variable
Sol = 0                      ' Reset solution counter
x = DoMin - Pdx              ' Incremention at top of loop, back up one step
xi = Pdx                     ' Set increment to initial value
TimeStop = TIMER + AborTime  ' Set abort timer
Abort$ = Null$               ' Set abort message to null string
DO:
  x = x + xi                 ' Increment x
  GOSUB Selfunc              ' Evaluate selected function at x
  y1 = y                     ' Retain y at this point
  x = x + xi: GOSUB Selfunc  ' Repeat for next adjacent x value
  y2 = y: x = x - xi

'  For positive slope, test if given value, YofX, is between these two values,
'  if it is then back up one step, refine increment by .1*xi, back up one step
'  of refined increment.

IF YofX >= y1 AND YofX < y2 THEN GOSUB BackUp

'  For negative slope, repeat same process of backing up.

IF YofX <= y1 AND YofX > y2 THEN GOSUB BackUp

IF xi < (Tol# * .001) THEN  ' Assume discontinuity,
  x = x + Pdx: xi = Pdx     ' Skip this interval and reset increment value
  GOTO SkipPoint1           ' Skip over rest of loop.
END IF

IF ABS(YofX - y1) <= Tol# THEN  ' If absolute difference is within tolerance
   Sol = Sol + 1                ' increment solution counter
   xOFy(Sol) = x                ' save x solution
   xi = Pdx                     ' reset increment to original value
   x = x + xi                   ' step forward one to avoid repeating
END IF                          ' this solution

IF Progress = 1 THEN            ' If progress switch is on then display this
  FOR I = 1 TO 10: LOCATE I, 40: PRINT BlkHL$: NEXT I
  LOCATE 1, 40: PRINT "    Progress"
  LOCATE 2, 40: PRINT "xinc = "; xi
  LOCATE 3, 40: PRINT "   x = "; x
  LOCATE 4, 40: PRINT "  y1 = "; y1
  LOCATE 5, 40: PRINT "YofX = "; YofX
  LOCATE 6, 40: PRINT "  y2 = "; y2
  LOCATE 7, 40: PRINT " Sol = "; Sol
  PauseTime = TIMER + .05             ' Hesitate display to avoid flicking
  DO: LOOP UNTIL TIMER > PauseTime
END IF

SkipPoint1: ' Jump here if function discontinuity

GOSUB ChkTime   ' Check to see if time limit has been exceeded,
                ' if true the set Abort$ message to display such.
                ' Do loop until one of these has occurred,
                ' INKEY$ is manual abort

LOOP UNTIL x >= DoMax OR Sol >= 10 OR TIMER > TimeStop OR INKEY$ <> ""

CASE 2 ' Inflextion, local max, local min points
Feq = Feq0
xi = Pdx
TimeStop = TIMER + AborTime
Abort$ = Null$
Slope = 1              ' Slope switch: 1 = positive,   -1 = negative
Rate = 1               ' Slope rate:   1 = increasing, -1 = decreasing
x = DoMin              ' Evaluate f(x) at initial point and next 2 points
GOSUB Selfunc: y1 = y
x = x + xi
GOSUB Selfunc: y2 = y
x = x + xi
GOSUB Selfunc: y3 = y
dydx1 = (y2 - y1) / xi           ' Slope over first interval
dydx2 = (y3 - y2) / xi           ' Slope over second interval
IF dydx1 < 0 THEN Slope = -1     ' Reset slope switch if negative
IF dydx1 > dydx2 THEN Rate = -1  ' Reset rate switch if decreasing
x = DoMin - xi                   ' Incremention at top of loop
Sol1 = 0: Sol2 = 0: Sol3 = 0     ' Reset solution counters
LocMin = -1: LocMax = -1         ' Set local minimum, maximum switches
Inflex1 = -1: Inflex2 = -1       ' Set inflection switches
DO
x1 = x                             ' Retain current point as a solution
GOSUB Selfunc: y1 = y              ' Evaluate f(x) at current point and
x = x + xi: GOSUB Selfunc: y2 = y  ' the next two points
x = x + xi: GOSUB Selfunc: y3 = y
x = x - xi                         ' Back up one point for next iteration
dydx1# = (y2 - y1) / xi            ' Slope of first interval
dydx2# = (y3 - y2) / xi            ' Slope of second interval

' If current slope is negative and the previous slope positive then
' a local maximum point present.  Set LocMax switch and do the BackUp.
' If current slope is positive and the previous slope negative then
' a local minimum point is present. Set LocMin switch and do the BackUp.

IF dydx1# < 0 AND Slope = 1 THEN LocMax = 1: GOSUB BackUp  ' + to - change
IF dydx1# > 0 AND Slope = -1 THEN LocMin = 1: GOSUB BackUp ' - to + change

' If current slope rate is decreasing and rate was increasing or
' if current slope rate is increasing and rate was decreasing then
' an inflection point is present. Set Inflec1 switch and do BackUp routine.

IF dydx1# > dydx2# AND Rate = 1 THEN Inflex1 = 1: GOSUB BackUp  ' - to +
IF dydx1# < dydx2# AND Rate = -1 THEN Inflex2 = 1: GOSUB BackUp ' + to -

IF xi < Tol# THEN                    ' If accuracy has been achieved then
  IF LocMin = 1 AND Sol1 < 10 THEN   ' determine which type of solution it is
    Sol1 = Sol1 + 1                  ' increment the solution counter
    LYmn(Sol1) = y1: LXmn(Sol1) = x1 ' save the y and x values
    LocMin = -1: Slope = 1           ' reset switches appropriately
  END IF                             ' also check for maximum number
  IF LocMax = 1 AND Sol2 < 10 THEN   ' of solutions in arrays
    Sol2 = Sol2 + 1
    LYmx(Sol2) = y1: LXmx(Sol2) = x1
    LocMax = -1: Slope = -1
  END IF
  IF (Inflex1 = 1 OR Inflex2 = 1) AND Sol3 < 10 THEN
    Sol3 = Sol3 + 1: FPy(Sol3) = y1: FPx(Sol3) = x1
    IF Inflex1 = 1 THEN Rate = -1
    IF Inflex2 = 1 THEN Rate = 1
    Inflex1 = -1: Inflex2 = -1
  END IF
  xi = Pdx
END IF

IF Progress = 1 THEN         ' If Progress switch is one then display this
  FOR I = 1 TO 10: LOCATE I, 40: PRINT BlkHL$: NEXT I
  LOCATE 1, 40: PRINT "     STATUS"
  LOCATE 2, 40: PRINT "xinc = "; xi
  LOCATE 3, 40: PRINT "   x = "; x
  LOCATE 4, 40: PRINT "  y1 = "; y1
  LOCATE 5, 40: PRINT "Solutions:"
  LOCATE 6, 40: PRINT "LocMin = "; Sol1
  LOCATE 7, 40: PRINT "LocMax = "; Sol2
  LOCATE 8, 40: PRINT "Inflec = "; Sol3
  PauseTime = TIMER + .05                 ' Hesitate to avoid flicking
  DO: LOOP UNTIL TIMER > PauseTime
END IF

GOSUB ChkTime

LOOP UNTIL x > DoMax OR TIMER > TimeStop OR INKEY$ <> Null$

CASE 3 ' Intersection
Sol = 0                     ' Reset solution counter
x = DoMin - Pdx             ' Incremention at top of loop
xi = Pdx                    ' Set initial increment value
Test = -1                   ' Test switch: 1st function > 2nd function = 1
                            '              1st function < 2nd function = -1
TimeStop = TIMER + AborTime ' Set loop timeout limit
Abort$ = Null$              ' and null abort message

Feq = Feq1: GOSUB Selfunc: y1 = y  ' Evaluate 1st function
Feq = Feq2: GOSUB Selfunc: y2 = y  ' Evaluate 2nd function
IF y1 > y2 THEN Test = 1           ' Reset Test switch if required
DO
x = x + xi                         ' Increment to next x value
Feq = Feq1: GOSUB Selfunc: y1 = y  ' Evaluate 1st function
Feq = Feq2: GOSUB Selfunc: y2 = y  ' Evaluate 2nd function

' If increment value is now less than tolerance
' assume a discontinuity at this interval and skip over it.

IF xi < (Tol# * .001) THEN
  Test = -Test              ' For discontinuity relative position has changed
  x = x + Pdx: xi = Pdx     ' Skip this interval and reset increment value
  GOTO SkipPoint3           ' Skip over rest of loop.
END IF

' If relative position of functions has changed then do BackUp routine

IF y1 > y2 AND Test = -1 THEN GOSUB BackUp ' 1st > 2nd and was 1st < 2nd
IF y1 < y2 AND Test = 1 THEN GOSUB BackUp  ' 1st < 2nd and was 1st > 2nd

IF ABS(y1 - y2) < Tol# THEN   ' If accuracy has been achieved then
  Sol = Sol + 1               ' increment solution counter
  Y1eqY2atX(Sol) = x          ' save x solution and
  y1atx(Sol) = y1             ' use 1st function value as y solution
  Test = -Test                ' reset Test switch
  xi = Pdx                    ' reset increment to original value
END IF

IF Progress = 1 THEN          ' If Progress switch is on then display this
  FOR I = 1 TO 10: LOCATE I, 40: PRINT BlkHL$: NEXT I
  LOCATE 1, 40: PRINT "     STATUS"
  LOCATE 2, 40: PRINT "xinc = "; xi
  LOCATE 3, 40: PRINT "   x = "; x
  LOCATE 4, 40: PRINT "f1(x)= "; y1
  LOCATE 5, 40: PRINT "f2(x)= "; y2
  LOCATE 6, 40: PRINT " Sol = "; Sol
  PauseTime = TIMER + .05            ' Hesitate to avoid flickering
  DO: LOOP UNTIL TIMER > PauseTime
END IF

SkipPoint3: ' Jump here if discontiuity this inteveral.

GOSUB ChkTime
LOOP UNTIL x > DoMax OR Sol >= 10 OR TIMER > TimeStop OR INKEY$ <> Null$

END SELECT

AnaDone$ = Done$
RETURN

BackUp:
IF xi > (Tol# * .001#) THEN x = x - 1 * xi: xi = xi * .1: x = x - xi
RETURN

ChkTime:
  IF TIMER > TimeStop THEN
     BEEP: Abort$ = "Exceeded time limit, analysis incomplete."
  END IF
RETURN

' ********************
' FUNCTION DEFINITIONS
' ********************
'
' User should use QB45 or other basic language environment to define the 
' FUNCTIONS FUNC1#(x, D$),  FUNC2#(x, D$), ...  which are to be analyized.
' The code can be simple equations or complex numerical models within each
' function definition.
'
' There are probably several ways to manage these function definitions for 
' different applications or problems. Two suggested methods follow.
'
' First method.
' 1. Save the MAIN PROGRAM code, ie, everything but FUNCTIONS under one file
'    name.  SAVE AS PLAIN TEXT ASCII.
' 2. Develop function definitions and save under a filename unique for each
'    problem. SAVE AS PLAIN TEXT ASCII.
' 3. Append the FUNCTIONs file to the MAIN PROGRAM file and run the program.

' Second method.
' 1. Save MAIN PROGRAM and FUNCTIONs definitions as one file for each 
'    application or problem.
' 2. Use of this methods allows easier development of FUNCTION code within
'    the language environment.

END  ' End of MAIN PROGRAM code

FUNCTION FUNC1# (x, D$)
D$ = "sin(x)"
FUNC1# = 1! * SIN(x)
END FUNCTION

FUNCTION FUNC2# (x, D$)
D$ = "tan(x)"
FUNC2# = TAN(x)
END FUNCTION

FUNCTION FUNC3# (x, D$)
D$ = "y = .75"
FUNC3# = .75
END FUNCTION

FUNCTION FUNC4# (x, D$)
D$ = "x^2+x+0"
FUNC4# = x ^ 2 + x + 0
END FUNCTION

FUNCTION FUNC5# (x, D$)
D$ = "y=.5"
FUNC5# = .5
END FUNCTION

FUNCTION LGT (x#)
   LGT = LOG(x#) / LOG(10#)
END FUNCTION

' Delete the below lines and this one.
1