DECLARE SUB help ()
DECLARE SUB getval (z#)
DEFDBL A-H, P-Z
DEFINT I-O

' ITERANT.BAS
'   Generates Iteration plots (such as bifurcation plots) interactively
'   with a primative/simple user interface.
'   Written by J.I. Landman 4/11/91, under QuickBasic version 4.5
'   Copyright 1991, J.I. Landman
'       Permission is granted to distribute,
'   use, copy, generate interesting plots, butcher and enhance the code,
'   with 2 absolute requirements.  1) With the modified program, you must
'   distribute this unmodified code in its original form.  2) Any original
'   work that is published in any Journal/Magazine/Newspaper/Disk/Newsgroups
'   et cetra, based upon this code or its modifications must have a
'   citation of the original code/author (eg me).
'       I place this code entirely within the public domain.  I accept no
'   responsibility for damages incurred from the use and/or misuse of this
'   code/data.  As the great numerical analyst Dr Jack Dongarra has said:
'   "CAVEAT RECEPTOR:  Nothing that is free comes with any guaranty"
'       I can be reached via the mail at
'       J.I. Landman
'       Physics Bldg, 666 Hancock Avenue,
'       Wayne State University, Detroit MI 48202
'   or over the internet/bitnet networks at
'       07480JLN@MSU.BITNET
'       07480JLN@CMS.cc.msu.edu
'       userzv50@mts.cc.wayne.edu
'       userzv50@waynemts.bitnet
'   I invite correspondence, especially about interesting iterants, physics,
'   programming, mathematics, etc.
'
' 


'Useful quantities
    xl = -2 'initial window size (physical size is fixed on the
    xh = 1 / 4 ' screen, but not in terms of the area we can view)
    yl = -4
    yh = 4
    npts = 150  ' number of points in a window

    ito = 75    '   iteration ending default value
    ifrom = 50  '   iteration starting default value


'BEGIN: Main code loop
startup:
    CLS
    SCREEN 3 'change this to suit your screen needs
         ' use screen 2  for CGA
         ' use screen 8,9,10,11,12,13 for EGA/VGA/MCGA
    th = (yh - yl) / 40 '   tic height on y axis being 1/40th the y length
    cth = (xh - xl) / 40'   tic height on x axis ...

    LOCATE 22, 40   ' blank the message area
    PRINT SPACE$(39)
    LOCATE 21, 40
    PRINT SPACE$(39)
    LOCATE 20, 40
    PRINT SPACE$(39)


    VIEW (50, 0)-(500, 222) ' define graphics viewport on screen
                            ' this wont work correctly on 320x200 screen
                            ' modes such as 1.  Change the 500 to 216
                            ' and the 222 to 142
                            ' the text will not work properly in this screen
                            ' mode (320x200)
   
    WINDOW (xl, yl)-(xh, yh)' setup the graphics window dimensions
    LINE (xl, yl)-(xh, yh), , B ' draw a box around it

    delc = (xh - xl) / 5    ' begin tic placement
    FOR cx = xl TO xh STEP delc
        LINE (cx, yl)-(cx, yl + th)
        LINE (cx, yh)-(cx, yh - th)
    NEXT
    FOR cx = xl TO xh STEP delc / 2
        LINE (cx, yl)-(cx, yl + th / 2)
        LINE (cx, yh)-(cx, yh - th / 2)
    NEXT
    dely = (yh - yl) / 5
    FOR y = yl TO yh STEP dely
        LINE (xl, y)-(xl + cth, y)
        LINE (xh, y)-(xh - cth, y)
    NEXT
    FOR y = yl TO yh STEP dely / 2
        LINE (xl, y)-(xl + cth / 2, y)
        LINE (xh, y)-(xh - cth / 2, y)
    NEXT

    i = 1   ' begin text placement: I tweaked it until it worked on the herc
    'ules screen.  You may need to change the locate statements
    FOR xx = xl TO xh STEP delc
        LOCATE 18, i + 9 * i - 8
        PRINT USING "##.######"; xx
        i = i + 1
    NEXT
    LOCATE 19, 31
    PRINT "X"
    i = 1
    FOR yc = yl TO yh STEP dely
        LOCATE 19 - 3 * i, 57
        PRINT USING "##.######"; yc
        i = i + 1
    NEXT
    LOCATE 9, 67
    PRINT "Y"

display:    ' main display loop
    dc = (xl - xh) / npts '  step size along xaxis

    LOCATE 21, 4    ' show current values of useful quantities
    PRINT USING "Xlow=##.######,   Xhigh=##.######"; xl; xh
    LOCATE 22, 4
    PRINT USING "Ylow=##.######,   Yhigh=##.######"; yl; yh
    LOCATE 23, 4
    PRINT USING "  npts=######,    from=###, to=###"; npts; ifrom; ito
    LOCATE 21, 40

    PRINT "item to change:";    'prompt user for item to change
    LINE INPUT q$   ' get it
    q$ = LTRIM$(RTRIM$(LCASE$(q$))) ' get rid of any spaces and make lowercase
    SELECT CASE q$
    CASE "xl", "xlo", "xlow", "xmin"
        LOCATE 20, 40
        PRINT "Modifying Xlow"
        CALL getval(xl)
        GOTO startup
    CASE "xh", "xhi", "xhigh", "xmax"
        LOCATE 20, 40
        PRINT "Modifying Xhigh"
        CALL getval(xh)
        GOTO startup
    CASE "yl", "ylo", "xlow", "ymin"
        LOCATE 20, 40
        PRINT "Modifying Ylow"
        CALL getval(yl)
        GOTO startup
    CASE "yh", "yhi", "yhigh", "ymax"
        LOCATE 20, 40
        PRINT "Modifying Yhigh"
        CALL getval(yh)
        GOTO startup
    CASE "go", "start", "begin", "plot", "graph", "run", "execute"
        GOTO endofselect
    CASE "end", "quit", "finish", "stop"
        STOP
    CASE "n", "num", "npt", "npts", "number"
        LOCATE 20, 40
        PRINT "Modifying npts"
        xxx = npts
        CALL getval(xxx)
        npts = xxx
    CASE "to", "until", "last"
        LOCATE 20, 40
        PRINT "Modifying TO"
        xito = ito
        CALL getval(xito)
        ito = CINT(xito)
    CASE "from", "first"
        LOCATE 20, 40
        PRINT "Modifying FROM"
        xf = ifrom
        CALL getval(xf)
        ifrom = CINT(xf)
    CASE "clear", "cls", "new"
        GOTO startup
    CASE "help", "?"
        CALL help
        GOTO startup
    CASE ELSE
        LOCATE 21, 40
        PRINT SPACE$(39)
        LOCATE 22, 40
        PRINT SPACE$(39)
        LOCATE 20, 40
        PRINT SPACE$(39)


        '
    END SELECT  ' end of user interface loop
    LOCATE 20, 40
    PRINT SPACE$(39)
    GOTO display

    
endofselect:


    xn = 0

    FOR x = xh TO xl STEP dc
        yn = 0
        i$ = ""
        FOR i = 1 TO ito
        'THIS IS IT!!!! THE NEXT LINE IS ALL THE PROCESSING THIS PROG DOES
            yn = yn * yn + x

        '    yn = SQR(ABS(yn)) + x
        ' other interesting ones are
        '   yn=abs(yn)^(-sqr(sqr(sqr(abs(yn)))))+x
        '   yn=yn*sin(yn)+x
        '   yn=yn*cos(yn*yn)+x


            i$ = INKEY$
            IF (i > ifrom) THEN PSET (x, yn)
            IF i$ <> "" THEN
                SOUND 60, 1
                GOTO display
            END IF
        NEXT
    NEXT
    SOUND 70, 1
    GOTO display

SUB getval (z)
    LOCATE 21, 40
    PRINT USING "old value = ##.######"; z
    LOCATE 22, 40
    PRINT "New value is:";
    INPUT qq$
    qq$ = LTRIM$(RTRIM$(LCASE$(qq$)))
    IF qq$ <> "" THEN
        x = VAL(qq$)
        IF ((x <> 0) AND (x <> z)) THEN
            z = x
        END IF
    END IF
    LOCATE 21, 40
    PRINT SPACE$(39)
    LOCATE 22, 40
    PRINT SPACE$(39)

END SUB

SUB help
    SCREEN 0
    CLS
    PRINT "ITERANT by J.I. Landman.  Copyright 1991, by J.I. Landman"
    PRINT " To adjust the parameters, type in the name of the parameter"
    PRINT " at the prompt.  You will be asked for a new value.  If you"
    PRINT " press enter without giving a value, the program will retain the"
    PRINT " current one."
    PRINT "  to start an ITERATION calculation, type the word GO at the"
    PRINT " prompt.  to stop it press any key, and then type the word STOP"
    PRINT
    PRINT "press any key to continue:"
    WHILE INKEY$ = ""
    WEND
    
END SUB

