Logistic Map
May 29, 2019
There’s nothing tricky about this:
; logistic map (define r #f) (define x #f) (define (reset z) (set! r z) (set! x 0.5)) (define (logistic) (let ((new-x (* r x (- 1 x)))) (set! x new-x) x)) (define (drop n) (do ((n n (- n 1))) ((zero? n)) (logistic))) (define (take n) (let loop ((n n) (zs (list))) (if (zero? n) (reverse zs) (loop (- n 1) (cons (logistic) zs)))))
The tricky part is looking at the results. With r = 0.75, the sequence tends to zero:
> (reset 0.75) > (drop 1000) > (take 10) (1.1801375113691321e-126 8.851031335268491e-127 6.638273501451368e-127 4.978705126088526e-127 3.734028844566395e-127 2.8005216334247964e-127 2.1003912250685973e-127 1.575293418801448e-127 1.181470064101086e-127 8.861025480758144e-128)
With r = 1.75, the sequence tends to a single non-zero value:
> (reset 1.75) > (drop 1000) > (take 10) (0.42857142857142855 0.42857142857142855 0.42857142857142855 0.42857142857142855 0.42857142857142855 0.42857142857142855 0.42857142857142855 0.42857142857142855 0.42857142857142855 0.42857142857142855)
Likewise with r = 2.75:
> (reset 2.75) > (drop 1000) > (take 10) (0.6363636363636365 0.6363636363636362 0.6363636363636365 0.6363636363636362 0.6363636363636365 0.6363636363636362 0.6363636363636365 0.6363636363636362 0.6363636363636365 0.6363636363636362)
But with r = 3.75, the results are chaotic:
(reset 3.75) > (drop 1000) > (0.8591179385506535 0.45387864829173385 0.9295230784372591 0.24566221908667554 0.6949210995003217 0.7950216186359463 0.6111084170153485 0.8912059487562879 0.36359214621634744 0.8677233653480164)
I’ll be reading some more about chaos. You can run the program at https://ideone.com/N5zQ93.
Here’s a Haskell program that prints the bifurcation diagram for the logistic map. I’ve included output for a couple of ranges of r values.
Zooming in on the region 3.4 <= r <= 3.7.
Here’s a solution in Python that shows a bifurcation diagram, inspired by @Globules’s solution above.
Output: