The Logistic Map & the Onset of Chaos, Sonified
System Dynamics Modeling & Audio Synthesis in Max/MSP
Some friends asked me to play a set at a show I was helping book & promote, as I used to do much more in a near-past life. Since I hadn’t been in the ‘music / art / aesthetics’ state of mind or being for quite some time, I thought I’d take the opportunity to explore some of the concepts I’ve been studying in Complexity & System Dynamics.
In particular, I took up one of the most compelling subjects I’ve encountered thus far (among many): the simple yet profound equation — technically, recurrence relation — known as the ‘Logistic Map’.
The Logistic Map
Quoth wikipedia:
The logistic map is a polynomial mapping (equivalently, recurrence relation) of degree 2, often cited as an archetypal example of how complex, chaotic behaviour can arise from very simple non-linear dynamical equations. The map was popularized in a seminal 1976 paper by the biologist Robert May, in part as a discrete-time demographic model analogous to the logistic equation first created by Pierre François Verhulst.
In math, the model looks like this:
where ‘x’ is a number between zero and one that represents the ratio of existing population to the maximum possible population. The values of interest for the parameter r are those in the interval [0,4]. This nonlinear difference equation is intended to capture two effects:
* reproduction where the population will increase at a rate proportional to the current population when the population size is small.
* starvation (density-dependent mortality) where the growth rate will decrease at a rate proportional to the value obtained by taking the theoretical “carrying capacity” of the environment less the current population.
Without getting too deep here, the basic idea is that the equation produces a sequence of values for x where, through iteration, the current value of x is plugged into a simple operation to produce the next value of x at the subsequent step in the discrete time sequence. And to reiterate, x represents the ratio of the current ‘population’ to the total possible population of the system.
The magic & mystique happens as r — which can be thought of as the ‘growth rate’ of the population — increases from 0 → 4. Up until an r of about 3, x remains remarkably stable as the equation is iterated, climbing only slightly. After that, the model settles into a fixed point attractor dynamic with period 2, which just means that x oscillates between 2 fixed values. This only lasts for a bit, however, until the system enters a period-doubling window where x begins to oscillate between 4, then 8, 16, 32, etc values. This is also a precious brief moment, the end of which is known as the ‘edge of chaos’ or ‘onset of chaos’, due to the lack of discernible or predictable patterns in the behavior of x after this point, which will vary tremendously given only slight variance in initial conditions. (This brings us to one prominent technical definition of ‘chaos’: sensitive dependence on initial conditions).
The above behavior is perhaps most strikingly & gorgeously visualized in the iconic ‘bifurcation diagram’:
With x on the vertical axis, & r on the horizontal, the behavior described above is stunningly depicted: the initial stability, the first divergence into fixed point attractor oscillation between 2 values, & finally the period-doubling window quickly giving way to chaotic frenzy.
It was this behavior I sought to simulate & sonify in my Max/MSP program.
The Max Patch
Max is a visual programming language with specific application in audio synthesis & generative multimedia. Programs, or patches, consist of objects with various functions, some of which compute numbers & data, some of which compute & transmit audio signals or visual information. I won’t get into detail about the language & programming environment, but I will explain the major elements in my patch & what they do.
This is the meat of the patch, where I implement the Logistic Map equation, & pass the resulting outputs to other modules for processing into audio & visual information.
The centerpiece is the equation itself, which in Max language looks like: expr [$f1*$f2]*[1-$f2]
(2nd from bottom-right; using an expr
object, which encodes mathematical expressions).
If unclear, this expresses the right side of the Logistic Map equation, substituting $f1
for r & $f2
for x_n. This is how Max deploys variables, $f
for floats & $i
for integers. The numbers 1
& 2
in $f1
& $f2
are just indexes, which correspond to the left & right ‘inlets’ on the top of the object, where the values for each variable are fed (via gray patch cables).
The number objects storing the values for x and r are labelled, & worth paying attention to throughout the video embedded above. I initiate the system with an x of .6
(for numerological nerd reasons related to the date of the performance), & r of 1
(systems tend to ‘die out’ with r < 1).
The equation is then iterated, with the outputted value being fed back into the labelled ‘x’ number object, then fed again into the equation expr
object.
The value for r is controlled by the metro
object (a metronome), which fires a signal 3 times a second (technically, every 333
milliseconds). That signal is fed into the counter object, which advances once each time the signal is received. The counter value is then passed into another expr
object (bottom-right) which multiplies it by .001
& adds 1
to the result. This is just a somewhat convoluted way to initiate r at 1
, & then advance it by .001
at each ‘time step’, which occur every 333 milliseconds. The metro
pulse signal also synchronizes the entire patch / system, for instance: triggering each iteration of the main equation 3 times per second.
(Note: the simulation doesn’t actually begin until I trigger the ‘toggle’ object, depicted as a small square box with an X in it at the top-left above, under the title. Prior to that in the video, I’m just initializing the patch parameters)
The entire top-left of the patch is all related to the audio / ‘musical’ aspects of the program.
Won’t go into detail here, but the main point is that it takes in the current value of x at the top-right, scales it to an integer in an audible frequency range (steering clear of higher, shrill frequencies), then feeds the output into an oscillator which produces an audio signal sine wave at the given frequency. After that, I do a bit of signal processing just to shape the sound a little bit. This includes manipulating the amplitude, EQ & ADSR of the signal, along with some delay feedback.
Takeaway: the main central pulse you hear in the piece is the sonification of the current value of x. That is the object of interest in the Logistic Map, & you can keep track of its value & the audio frequency translation into by keeping an eye on the relevant objects in the patch. (‘x’ is labelled; frequency is depicted in the objects that read 110
in the image above).
I’ll describe the visualizations in a moment, which also depict the dynamic values being produced by the system. But first, you might also wonder about the sporadic ‘swells’ of other sounds around the main pulse in the piece. These are just accoutrements I included to add interest. They are produced by the DM_interval
subpatches, which take the current frequency, multiply it by 1.33
& 1.66
respectively, but only trigger sounds when r is a prime number. (Technically, when r * 1000
is prime). This is determined via the DM_isprimeto4000
subpatch, which just contains a list of prime numbers up to 4000 & performs a lookup.
Alright, onto the visualizations, which account for most of the visual interest of the patch.
Starting at the top-left, this spectroscope~
object visualizes audio signal content in time. I configured this one to depict frequency on the x-axis (higher markings = higher pitch), & amplitude intensity via opacity. So it ends up being a realtime, scrolling visualization of the main pulse in the patch (i.e. x, translated into sound). When x is stable, this visual pulse is stable too.
Directly under that is a fairly typical (for weirdo electronic music) spectral plot of the normalized frequency & magnitude of the current waveform. Not much to see here, but I was interested to keep track. It uses the plot~
object & Spectral Plot
‘Prototype’ in Max.
Then the main attraction, to the right above (center-bottom in the full patch), is the lcd
object, which basically allows you to draw things via x-y
coordinate inputs, among other things. Here, I clearly have 2 meaningful coordinates (x & r), so my intent was to sort of reproduce the Bifurcation Diagram shown below (to the right of the lcd
object). That diagram depicts x on the vertical (y) axis, & r on the horizontal (x) axis, so that’s what I did too. The results end up strikingly similar:
The major differences are both the resolution/dimensions & the fact that lcd
works like an etch-a-sketch, where the ‘pen’ never can lift from the page, so even as x oscillates between 2 values, everything in between gets ‘colored in’ as well.
The important thing here is to watch as r steadily advances rightward (at a rate of .001
each time-step) x stays tremendously stable, rising only slightly, although the equation is being iterated 3 times a second. That lasts until r gets to a bit over 3, which lasts until 3.5, etc. as I recount above in the Logistic Map section.
And, no spoilers, but I will mention that the video recording of this piece concludes in the same manner as every other time I’ve run this program, prior & since. I believe this has something to do with attempts to compute exponentially shrinking fractions / floats, but not sure.
The Moral
The only other major aspect of the patch is the Robert May quote from his seminal 1976 paper, Simple mathematical models with very complicated dynamics [pdf]. May is largely responsible for popularizing the Logistic Map & similar models, memorably & auspiciously characterizing their import as follows:
The fact that the simple and deterministic equation can possess dynamical trajectories which look like some sort of random noise has disturbing practical implications. It means, for example, that apparently erratic fluctuations in the census data for an animal population need not necessarily betoken either the vagaries of an unpredictable environment or sampling errors; they may simply derive from a rigidly deterministic population growth relationship…
Alternatively, it may be observed that in the chaotic regime, arbitrarily close initial conditions can lead to trajectories which, after a sufficiently long time, diverge widely. This means that, even if we have a simple model in which all the parameters are determined exactly, long-term prediction is nevertheless impossible
In addition to its obvious resonance with our current moment, this insight has become a bedrock principle of the study of Complexity in emerging fields such as Chaos theory, Information Theory, & Complex & Dynamical Systems Theory.
As I’ve remarked before:
I agree with Warren Weaver [pdf] that all of the non-physical sciences will have to absorb these insights to progress in the 21st century. (Or perhaps we need A New Kind of Science).
End of transmission.
—
Download the .wav or .mp3: here
Download the Max patch: https://github.com/dnlmc/lm_ooc
Follow on twitter: @dnlmc
LinkedIn: linkedin.com/in/dnlmc