McMullen carpets

A McMullen carpet is one of the simplest examples of a self-affine set that's not self-similar. To form a McMullen carpet, choose integers m and n such that 1 < m < n. Then, decompose the unit square into an m × n grid and select a subset of the resulting rectangles. If m = 2 and n = 3, then one such decomposition might look like so:

Note that this example above is generated dynamically; you can generate another example by hitting the redo button below. Many of the results below will automatically update as well.

Note that this decomposition implies an iterated function system consisting of 1 affine function - one that maps the unit square onto each of the rectangles that we see in the figure. The attractor of the IFS, in this particular case looks like so:

Dimension

There's a formula for the box-counting dimension of a McMullen carpet. In addition to m and n as defined above, let N denote the number of rectangles chosen to form the decomposition and let M denote the number of columns with at least one chosen rectangle. We'll also denote the attractor by C. Then, the box-counting dimension of C is [\text{dim}(C) = \frac{\log M}{\log m} + \frac{\log \left( N / M \right)}{\log n}.]

In the example above we have [\text{dim}(C) = \frac{\log 1}{\log 2} + \frac{\log \left( 1/1 \right)}{\log 3} \approx 0.]

Why so complicated?

The formula for the dimension of a McMullen carpet is somewhat more complicated than the box-counting dimension, and it's reasonable to ask if there's some fundamental reason why. Fundamentally, it comes down to the fact that the fractal dimension of self-affine sets is much more sensitive to the placements of the pieces when compared to self-similar sets - even when those pieces don't overlap at all.

We can illustrate this using the example below. The image is generated by an IFS with three functions, all with the same linear part, namely: [ A = \begin{pmatrix} 1/2 & 0 \ 0 & 1/5 \end{pmatrix}. ]

The IFS is then [\begin{aligned} f_1(x,y) &= A \begin{pmatrix} x \ y \end{pmatrix} \ f_2(x,y) &= A \begin{pmatrix} x \ y \end{pmatrix} + \begin{pmatrix} s \ 2/5 \end{pmatrix} \ f_1(x,y) &= A \begin{pmatrix} x \ y \end{pmatrix} + \begin{pmatrix} 0 \ 4/5 \end{pmatrix}. \end{aligned} ]

Note that s is a parameter that determines how far the second function shifts to the right. The "Shift" slider below sets the value of s to be something between 0 and 1/2.

Simple code to generate your own

Here's some code that makes it easy to generate your own McMullen carpet!

Code

[ \text{exampleIFS} = \text{IteratedFunctionSystem} { \text{affine,lists}: \text{Array}(1), \text{length}: 1, \text{affine_function_list}: \text{Array}(1), \text{function_list}: \text{Array}(1), \text{are_similarities}: \text{false}, \text{norms}: \text{Array}(1), \text{is_contractive}: \text{true}, \text{dimension}: -1.155757152647625e-13, \text{plist}: \text{Array}(1) } ]

[ mn = \text{Object} { c: 0.22421901012429304, m: 2, n: 3 } ]

[ \text{import} { \text{IteratedFunctionSystem} } \text{from} "@mcmcclur/iterated-function-systems"
]

{ // Note how the 0-1 pattern in the matrix below specifies // which sub-rectangles are on or off in the image. let M = [ [0,1,1], [1,0,0], [0,1,0], [0,1,1] ];

// The rest should be automatic. let m = M[0].length; let n = M.length; let A = [ [1/m,0], [0,1/n] ]; let IFS = [];
for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { if (M[j-1][i-1]) { IFS.push([A, [(i-1)/m, 1-j/n]]); } } }

return new IteratedFunctionSystem(IFS).render_stochastic({ n: 60000, colors: true, axes: true, extent: [[-0.05,1.05],[-0.05,1.05]], image_width: width < 900 ? width : 900 }); }

]