## Logistic Map

### May 29, 2019

[ I apologize for posting this exercise on Wednesday morning instead of Tuesday morning. I got mixed up because of the three-day holiday weekend. ]

I recently came across the logistic map which is an example of how complex, chaotic behavior can arise from simple non-linear equations. The logistic map is written

xn+1 = rxn (1 − xn

where 0 < xn < 1 represents the ratio of the existing population to the maximum possible and 0 < r < 4 represents the stability in the model of population density. I can't do the logistic map justice here; look at the Wikipedia page and follow the references it gives for a fascinating introduction to chaos theory.

Your task is to write a program that computes sequences of the logistic map, and experiment with it. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 2 Responses to “Logistic Map”

1. Globules said

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.

```import Data.List (nub, sort)
import System.Environment (getArgs, getProgName)

logistic :: Double -> Double -> [Double]
logistic r = iterate (\x -> r*x*(1-x))

-- A string with dots at the 1-based positions in ns.
dotsAt :: [Int] -> String
dotsAt ns = concat \$ zipWith dotAt (0:ns) ns
where dotAt i n = replicate (n-i-1) ' ' ++ "."

-- One row of dots corresponding to the x values that were visited for one value
-- of r.
oneRow :: Int -> [Double] -> String
oneRow cols = let w = 1/(fromIntegral cols - 1)
in dotsAt . nub . sort . map (\x -> floor (x/w) + 1)

-- One row of the bifurcation diagram, corresponding to one r value.  Drop some
-- initial values of the logistic map to let it converge to a value (if it in
-- fact will converge).
showRow :: Int -> Double -> Double -> String
showRow cols r = oneRow cols . take 100 . drop 1000 . logistic r

-- Plot the bifurcation diagram of the logistic map, for rmin ≤ r ≤ rmax, on a
-- graph having the given number of columns and rows.
plot :: Int -> Int -> Double -> Double -> Double -> IO ()
plot cols rows rmin rmax x =
mapM_ (\r -> putStrLn \$ showRow cols r x) \$ rs rows rmin rmax

-- N evenly spaced values of r, where rmin ≤ r ≤ rmax.
rs :: Int -> Double -> Double -> [Double]
rs n rmin rmax = let rb = (rmax - rmin)/(fromIntegral n - 1)
in [i*rb + rmin | j <- [0..n-1], let i = fromIntegral j]

data Args = Args Int Int Double Double deriving (Read)

parseArgs :: [String] -> Maybe Args
parseArgs args = readMaybe \$ "Args " ++ unwords args

main :: IO ()
main = do
prog <- getProgName
args <- getArgs
let x = 0.4 -- starting x value
case parseArgs args of
Just (Args width height rmin rmax) -> plot width height rmin rmax x
_ -> error \$ "Usage: " ++ prog ++ " width height rmin rmax"
```
```\$ ./logistic 120 50 2.8 3.8
.
.
.
.
.
.
.
.
.
.
.    .
.            .
.                .
.                   .
.                      .
.                        .
.                           .
.                             .
.                              .
.                                .
.                                  .
.                                    .
.                                     .
.                                      .
.                                       .
.                                         .
.                                          .
.                                           .
.                                            .
.                                             .
.                                              .
.                                               .
.   .                                             ..
.         .                                         .   .
.             .                                      .    .
.               .                                     .     .
.                 .                                   .       .
.  .              .     .                              . .     ..
......        ... .. .......                           ......   ...
................ . .. ....  .. ..                       .............
.......  .  . ..... ..  .. . .... ....                 ........ .......
....... ...     ... ... . ... . . .   .....            ............. .....
...........    . ...  .  ..   . ..... ... .  . ..     .... ..... ..... ....
. .... .  ..  ... .. ..  ..     ... ..  ..... ... .. .............  ..........
........ .   . ..  .  ...     ..   .... ..  .. . .... . ...... ... .  .........
..... .....    .    .. .. .      .. . ...  . ... . ...................  ... . ....
.                               .                  .                     .          .
......  ..   ..    .   ..  ... ..     ...  .  . . ........ .    .. . ..... ...... .....
... . ..   ..  ... ..    .  ..   ..  .. . .     ... ..  ..  ...     . ..  ..... .. ... ...
...    . .... ..   . .  .  . .    ..    . .   ..... .. .  .. .......... .... .. .......... .
```

Zooming in on the region 3.4 <= r <= 3.7.

```\$ ./logistic 120 50 3.4 3.7
.                                              .
.                                              .
.                                              .
.                                              .
.                                              .
.                                               .
.                                               .
.                                                .
.                                                .
.   .                                             . .
.      .                                           .  .
.       .                                          .  .
.         .                                         .   .
.         .                                        .    .
.           .                                       .    .
.           .                                       .    .
.             .                                      .     .
.             .                                      .     .
.               .                                     .     .
.               .                                     .     .
.                .                                   .      .
.                 .                                   .      .
.                 .                                   .       .
.                  .                                  .       .
..                .  .                                . .     ..
.  .              .    .                               . .     ..
.  .             .      .                              .  .    ..
.  .            . .     ..                            ..  .    ...
.. ...          ......  ....                           .. ...   ...
....  .       .    .  .   . .                          ... . .  ...
.   .. ..    .     ...       .                         ..  .. . ....
.........  .  ....   ..........                        ..... .......
..........  ..  .....   .. . ....                       .... ........
.... .....  . .....  ..  ....... .                     ...............
...... .............  . ... .  .....                    ...............
........ .......... ... .  ..... . ..                  ................
.... .......... ... .  .   . . .... ..                 . .... .........
.                     .                .               .       .       .
.                     .. .              ..             .      ..       ..
... . .           . .... ....   .     .....             ... . ......   ...
.... . ... ....  ....  ..   . . .. ..... .  .          ........ ..........
....  ...  .   . .     ..  ... . ...  .   .....        ..... .... . .. ....
....... .  .  .. . ..  ..   ...... .  ...  . . .       .......... .........
........  ...... . .....  . .  . .. ...  .... . ...    ..... ...............
.. .. .. . . .....  .   ..  . . ..... ...   ....  ..  ..... ...... . ........
.... ... .... . ....  .  . . .  . . .. . .   ...... .. . ... .................
.... .. .  .. ...  .... . .  . ... ... .. . .... .................. ... ......
.. ..    .    .   .   .    ... .. .     .   . ... ..... ...... .  ..... . .. ..
. ...  ..  .. .... . ... ...  .  .    ....... ..  ......... ..... . ...........
...  . .  . . .    .. .  ..  ......    ... .. .... ............... ....... ......
```
2. Daniel said

Here’s a solution in Python that shows a bifurcation diagram, inspired by @Globules’s solution above.

```import math

def logistic_map(x, r):
while True:
yield x
x = r * x * (1 - x)

CHAR = 'x'
INIT = 0.5
R_ITERS = 50
T_SKIP = 1000
T_KEEP = 1000
WIDTH = 80
R_MIN = 2.4 # inclusive
R_MAX = 4.0 # exclusive

r_range = R_MAX - R_MIN

for iter in range(R_ITERS):
r = R_MIN + iter * (R_MAX - R_MIN) / R_ITERS
gen = logistic_map(INIT, r)
chars = [' '] * WIDTH
for _ in range(T_SKIP):
next(gen)
for _ in range(T_KEEP):
x = next(gen)
idx = math.floor(x * WIDTH)
chars[idx] = CHAR
print(''.join(chars))
```

Output:

```                                              x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x    x
x          x
x              x
x                x
x                  x
x                    x
x                     x
x                       x
x                         x
x                          x
x                            x
x                             x
x                              x
x                               x
x  x                              xx
x       x                          x  x
x          x                        x    x
xx          x  x                    x x   xx
xxxxxx   xxxxxxxxxxxx                xxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx            xxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx      xxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xx                   xxxx          xx            xxx     x
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x                           x                                    x
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```