Contents

Self-Similarity and Recursion: The Cantor Set

As a straightforward example of self-similarity that may be used toward great musical effect, consider the Cantor Set shown below.

cantor

The steps required to create this self-similar design is as follows:

            (1) start with a horizontal line segment.

            (2) make a copy of this line immediately below it,

            (3) divide the new line into three parts. 

            (4) remove the middle of the three parts - as shown in the first two steps of the diagram above, we change from a single solid line to two smaller lines with a space in the middle.

            (5) for each of the two lines just made, repeat from step(2) above

That’s it!  That is all one needs to know (either a human or a computer), to create the full design of the Cantor Set.

To apply this design toward an arrangement of sound clips in EarSketch, we can use the line-by-line pattern of a Cantor Set to specify where sound clips should be placed on consecutive Reaper tracks, yielding something like this:

cantorSetInReaper

As part of the code example for this section, we’ve created a function that places sound clips on consecutive tracks in Reaper, according to the pattern of a Cantor Set.

makeCantorSet(musicList, 1, 1, 4, 4)

When calling the above function, we supply it with these parameters:

audioclips a list of audio clips (one for each track)
tracknum the track number we want it to start at
start the measure number we want it to start at
length the length of the full pattern in bars
depth a depth amount

The last parameter depth amount specifies the total number of tracks we want the function to create, which corresponds to the same number of lines in a Cantor set pattern (see the first diagram at the top).

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

We see that on lines 11 and 12, makeCantorSet() calls itself twice from within itself. Thus makeCantorSet() is a recursive function,  and its calls to itself on lines 11 and 12 are recursive calls.

Notice that in this example, there is more than one recursive call used within the definition of the function. These two recursive calls correspond to step(5) in the Cantor Set design instructions at the top of the page: one recursive call for each of the two new lines just created in step(4). And since there are two recursive calls here, each level of recursion has two times the number of recursive calls as the preceding level, shown by each level of the Cantor Set pattern – see both diagrams above !