Thursday, 18 August 2011

Chaos in Max and PureData

We've looked at a few algorithmic composition ideas using Chaos in OpenMusic here, today's post applies some of these ideas algorithmic composition ideas in Max and PureData.

Chaos theory is a field of mathematics where dynamic systems are very sensitive to initial conditions. The famous 'butterfly effect' states that small differences in initial conditions can lead to large variations later: the small flap of a butterfly's wings may cause effects that later alter the path of a tornado.

As with our OpenMusic chaos patch, for this example of Chaos in PureData and Max we'll use a logistic map. The Logistic Map is a simple example of a discrete dynamical system that actually names a whole family of iterative functions described by the very common Logistic Equation:

fn+1=cfn(1-fn)

That's to say: to get the next value of f, multiply the current values of c, f and (1 - f). This formula involves only 1 subtraction and two multiplies but it leads to chaotic behaviour. In this graph you can see with values of c below 3 the behaviour is very predicatable. However if c > 3.75 then very small changes in f lead to very large changes later on:

In contrast to the many random processes which produce indeterministic behaviour, the logistic map is strictly deterministic. For instance we can iterate a given function of the logistic map n times to determine its nth value. The nth value of the function is determined solely by the initial value, f0 and the function constant c. But exactly how the nth value depends on the initial conditions is hard to predict. The next illustration parallels two processes with only minimally altered initial values. This difference leads after an initial phase of almost parallel evolution to totally different behaviour in both processes. It is almost impossible to predict the exact iteration at which the two processes take on different behaviour.
Development of the logistic function for f0=.95 (red) and f0=.949999999 (blue) for c=3.75 in both cases. This minimal variation of the initial value yields dramatically different sequences for n>30.

Chaos in Max and PureData
We'll use an expr object to perform our calculation and store the results in a coll. Here we set the values for c and f at 3.75 and .95 respectively. The output of the expression is our new input for f.

We know modify the value of f slightly and store this under a new index in our coll.
And in Max

Here we read our chaotic values stored in the coll, mapping them to chromatic pitches across three octaves and output the two different variations to different MIDI channels.
Finally, using a major scale stored in a table
And in Max

We map them to the scale
In Max we've set the metro to 250 and added a 125ms delay to instrument two so that the notes are triggered alternately.

The contents of the pd octaves subpatch looks like this. This subpatch receives numbers between 0 and 36 in, it uses mod 7 to map to the seven degrees of the major scale and / 7 to add in our octaves.
As Max handles integers and floats slightly differently to PureData no int object is needed here for this 'p octaves' subpatch.

You can hear some example output of the patch here:

There are many more chaotic functions to explore and many more ways of mapping these to create different musical output. We'll be exploring some of these in a future algorithmic composition tutorial.

Anonymous said...

Hi,

Firstofall thank you very much for your tuto, it's very interesting material.

Just a question about this one though as I get a "couldn't create" error with the [merge] object, could you indicate me in which library I could find this object ? (found a [merge_any] in iemlib)
But I'd rather find a vanilla substitute of it... what is it supposed to do ? is it just like a [prepend] ?

Algorithmic said...

Hi
Thanks. Luckily it's an easy fix - merge is a message rather than an object. When you send the 'coll' a merge message it will append the incoming messages into the coll - so in this case all each new incoming note will be added to an index in the coll. In the coll, for each note we end up with a big list of notes that have followed that note in the analysed MIDI file.

Hope this works for you.