Iterating x = rx(1 - x)

This program draws the parabola of y = rx(1 - x) and then uses the line y = x, to bounce y back into x in endless iteration. It draws the current bounce lines in bright white and then fades them to dark blue ready for the next iteration. The program concurrently displays a time-line graph (x vs time) of the resulting output. A tone is sounded whose pitch relates to the current iteration's output value of x. You are invited to enter a value for r before the iterations start. Low values of r produce a smooth sigmoid. Higher values cause the curve to 'ring' at the top. Still higher values send it into periodic oscillation. When r reaches about 3.7 the system becomes chaotic. Beyond r = 4 the output values diverge to infinity.
'StdLog1.BAS
screen 9,3
color 7,0
th = 3                     'text horizontal bias
s = 1.5                    'horizontal scaling factor
n = 150                    'integral extent of the axes
h = 230                    'horizontal zero bias
v = 330                    'vertical zero bias
nn = 550                   'extent of time-series horizontal axis
hh = 25                    'time-series horizontal bias
vv = 160                   'time-series vertical bias
ss = 50                    'inter-iteration delay

'INPUT THE VALUE OF R
LAB:
  locate 16, th : print"Iterate the formula y = rx(1 - x)"
  locate 23, th : print"Press RETURN to exit program. "
  locate 17, th
  input"Enter r = ",r$  'input the growth factor for this run
  if r$ = "" then end   'exit if nothing entered
  r = val(r$)           'growth factor
  cls                   'clear the screen

'DISPLAY THE RUN INFORMATION
  locate 14, th : print"FEIGENBAUM'S EXPERIMENT"
  locate 16, th : print"Iterating the formula y = rx(1 - x)"
  locate 17, th + 2 : print"for r = "; r$
  locate 23, th : print"Press any key to stop program."
  locate 19, th : print"yMAX ="
  locate 20, th : print"yMIN ="

'DRAW AXES FOR THE TIME-SERIES DIAGRAM
  ts = 1                    'set time-series flag
  c = 3                     'set colour to cyan for axes
  t = nn : x = 0 : gosub p  'set pen to end of time axis
  t = 0 : gosub l           'draw line to time-series origin
  x = 1 : gosub l           'draw time-series y-axis
  locate  2,  3 : print "y"
  locate 12, 74 : print "time"

'DRAW THE GRAPH AXES FOR THE FEIGENBAUM DIAGRAM
  ts = 0                    'clear time-series flag
  x = 1 : y = 0 : gosub p   'set pen to end of x-axis
  x = 0 : gosub l           'draw line to origin
  y = 1 : gosub l           'continue line to end of y-axis
  locate 14, 43 : print "y"
  locate 24, 73 : print "x";

'DRAW THE DIAGONAL BOUNCE-LINE
  c = 11
  y = 0 : gosub p           'set pen to origin
  x = 1 : y = 1 : gosub l   'draw diagonal line to point 1,1

'DRAW THE CURVE OF THE NON-LINEAR DIFFERENCE FUNCTION
  x = .001 : gosub f : gosub p   'draw its starting point
  for x = .001 to 1 step .01 : gosub f : gosub l : next

'ITERATE NON-LINEAR DIFFERENCE FUNCTION UNTIL A KEY IS PRESSED
  oldx = 0
  t = 1                    'initialise the time
  u = 61                   'start of trace-clearing sweep
  ymax = 0                 'holds maximum excursion of y
  ymin = 1                 'holds minimum excursion of y
  x = .3                   'set initial value of input
  y = 0                    'for position of first plot
  gosub p                  'set plotting pen to starting value
  e = 0                    'reset the out-of-range flag

  while inkey$ = ""        'while user has not pressed a key...
    xx = x : yy = y        'store starting co-ordinates
    c = 15 : gosub w       'draw the two lines in bright colour
    for ft = 0 to ss:next  'delay to aid visibility of trace
    sound 120 * (y + y + y + y + y + 1), 1
    gosub TimeSeries       'put plot on time-series graph
    x = xx : y = yy        'retrieve the starting co-ordinates
    c = 1 : gosub w        're-draw the lines in dim colour
  wend : goto LAB          'return for next r-value when key hit


'TIMES-SERIES GRAPH PLOTTING ROUTINE
TimeSeries:
  ts = 1                   'set time-series flag
  c = 10
  newx = x                 'save new value of function output
  if t > nn then t = 1     'if end of sweep has been reached
  x = oldx : gosub p       'set to previous plot position
  t = t + 8                'increment the time axis
  x = newx : gosub l       'draw line to current plot
  oldx = x                 'save current x for next pass
  if u > nn then u = 1
  uu = u + hh : uuu = uu + 10
  for i = uu to uuu
    line (i, vv - n) - (i, vv - 1), 0 'draw trace-wiper in blue
  next
  u = u + 8
  ts = 0                   'clear time-series flag
return


'DRAW ONE VERTICAL/HORIZONTAL LINE-PAIR (L-SHAPE)
w:
  if e = 0 then            'provided y hasn't gone out of range
    gosub p                'set the start of the line
    gosub f                'iterate the non-linear function
    if y < 0 or y > 1 then 'if y is now out of range
      e = 1                'set the out-of-range flag
      locate 21, th : print"Gone out of range: y ="y"     "
    else
      gosub l : x = y      'draw the up-line 
      gosub l              'then across-line
    end if
  end if
return

p:
  gosub q : pset(a, b), c   'set starting point for current line
return

l:
  gosub q : line -(a, b), c 'draw line to point x, y
return

'CONVERT REAL X/Y CO-ORDINATES INTO SCALED INTEGRAL PIXELS
q:
  if ts = 0 then
    a = s * (h + n * x)
    b = v - n * y
  else
    a = hh + t
    b = vv - n * x
  end if
return

'ITERATE DIFFERENCE FUNCTION AND CHECK THAT RESULT IS IN RANGE
f:
  y = r * x * (1 - x)
  if y > ymax then ymax = y : locate 19, th + 8 : gosub num
  if y < ymin then ymin = y : locate 20, th + 8 : gosub num
return
num: 
  y$ = str$(y) : PRINT y$ + space$(13 - len(y$))
return

This page's parent within this Web Site. About this Web Site. Its home page. Email its Author.