Constructing Fractals and Fractal measures

This package focuses on self-similar fractals, which can be described by a finite set of self-similar maps. These maps are called similarities.

Similarities

Each similarity is of the form:

\[s_m(x)=\rho_mA_mx + \delta_m,\quad x\in\mathbb{R}^N,\]

where $\rho_m\in(0,1)$ is the contraction factor, $A_m\in\R^{N\times N}$ is a rotation matrix, and $\delta\in\R^{N}$ is a translation vector. Here we call $N\in\mathbb{N}$ the ambient dimension.

FractalIntegrals.SimilarityType
Similarity{N, T} <: AbstractSimilarity{N, T}

Constructs a similarity, which can be used to describe geometry of self-similar fractals. N is the dimension of the ambient space, and T<:Number.

Mathematically, this captures the following map:

\[s(x) = δ + ρAx, x ∈ ℝⁿ\]

Fields

  • ρ :: T: The contraction factor.
  • δ :: SVector{N,T}: The translation vector.
  • A :: SMatrix{N,N,T} : The rotation/reflection matrix.
  • ρA :: SMatrix{N,N,T} : The rotation/reflection matrix multiplied by the contraction factor.

Examples

s₁ = Similarity(1/3, [0,0])
s₂ = Similarity(Float32(1/3), rand(3), [-1 0; 0 1])

In the first example above, the third argument is not given, so it is assumed that A=I.

Various binary operations can be performed on Similarity:

s₂₁ = s₁ ∘ s₂
s₂⁻¹ = inv(s₂)
s₁³ = s₁^3

In each of the above examples, a Similarity is returned.

Similarity can be applied as a function

x = rand(2)
y = s₁(x)
source

Attractors

An iterated function system (IFS) is a set of $M$ similarities $\{s_m\}_{m=1}^M$, and an attractor of an iterated function system $\Gamma$ satisfies

\[\Gamma = \bigcup_{m=1}^M s_m(\Gamma)\]

FractalIntegrals.AttractorType
Attractor{N, M, T} <: AbstractAttractor{N, M, T}

An attractor of an iterated function system (IFS). In this context, an IFS should be interpreted as a set of similarities. Mathematically, an IFS attractor is the unique bounded non-empty set satisfying

\[Γ = ⋃ₘ sₘ(Γ)\]

where sₘ are similarities, defined in the docstring Similarity. For a fuller explanation, see for e.g. this wikipedia article https://en.wikipedia.org/wiki/Iterated_function_system.

Parameters

  • N is the ambient dimension of the attractor
  • M is the number of similarities
  • T<:Number is the numeric type

Fields

  • ifs::SVector{M, Similarity{N, T}}: iterated function system
  • diam::T: diamter of attractor
  • d::T: Hausdorff dimension of attractor
  • connectedness::Matrix{Bool}: matrix describing connected subcomponents
  • symmetries::Vector{Similarity{N, T}}: maps in symmetry group

Attractors can be constructed using a vector or tuple of similarities to represent the IFS; the diameter and Hausdorff dimension are computed automatically, the connectedness matrix is taken to be the identity, corresponding to a disjoint attractor, and the symmetry group is assumed to be the trivial group.

If the connectedness matrix is assumed to be the identity when the attractor is non-disjoint, this will impact accuracy of calculations of singular integrals.

Examples

s₁ = Similarity(1/3, 0)
s₂ = Similarity(1/3, 2/3)
cantor_set = Attractor(s₁, s₂)

courage = Similarity(1/2, [0, 0])
wisdom  = Similarity(1/2, [1/2, 0])
power   = Similarity(1/2, [1/4, sqrt(3)/4])
sierpinski_triangle = Attractor(courage, wisdom, power, connectedness = Bool(ones(3,3)))

Note how the connectedness matrix for the Sierpinski triangle is all ones, because the subcomponents all touch at the corners.

source
Fractal
├── AbstractAttractor
│   ├── Attractor
    ├── OneDimensionalAttractor
├── AbstractHomogenousAttractor
    ├── HomogenousAttractor
│   ├── OneDimensionalHomogenousAttractor

In general, an IFS attractor has a non-integer Hausdorff dimension. The Hausdorff dimension $d$ satisfies

\[\sum_{m=1}^M\rho_m^d = 1.\]

The following example constructs a Cantor set and displays its dimension.

s₁ = Similarity(1/3,0)
s₂ = Similarity(1/3,2/3)
Γ = Attractor(s₁, s₂)
print(Γ)
0.63-dimensional FractalIntegrals.OneDimensionalHomogenousAttractor{2, Float64}:
x ↦ 0.33x + 0.0
x ↦ 0.33x + 0.67
println("Full Hausdorff dimension of Cantor Set:", Γ.d)
Full Hausdorff dimension of Cantor Set:0.6309297535714574

Plotting attractors

Plots.plot has a method for a Attractor type.

plot(Γ, aspect_ratio=1)
Example block output

Presets

You can create your own attractor from scratch, as explained above. But a range of preset attractors are available.

FractalIntegrals.getfractalFunction
getfractal(T::Type, fractalname::Symbol; vargs...)
getfractal(T::Type, fractalname::String; vargs...)
getfractal(fractalname; vargs...)

Returns a preset fractal attractor corresponding to fractalname. This can be a sybol or a string.

Presets:

  • cantorset: Cantor Set
  • cantordust: Cantor Dust
  • sierpinskitriangle: Sierpinski Triangle
  • vicsek: Vicsek Fractal
  • kochcurve: Koch Curve
  • sierpinskicarpet: Sierpinski Carpet
  • heighwaydragon: Heighway Dragon
  • kochsnowflake: Koch Snowflake

Some of the presets will take an optional input argument. For example, the contraction factor ρ∈(0,1/2] of Cantor sets and dust.

Γ = getfractal("cantor set"; ρ = 1/4)
source
Γ = getfractal("sierpinskitriangle")
plot(Γ, aspect_ratio=1)
Example block output

Sub-components

It is often convenient to talk about a subcomponent of a fractal $\Gamma$ which is a scaled copy of the original $\Gamma$. This is particularly useful when meshing the fractal with fractal mesh elements. To do this, vector indexing is used, for example for $\mathbf{m}=[m_1,\ldots,m_\ell]$,

\[\Gamma_{\mathbf{m}} = s_{m_1}\circ \ldots \circ s_{m_\ell} (\Gamma)\]

This can be achieved by treating attractors as vectors.

Γ₁ = Γ[1]
𝐦 = [3,2,3,1]
Γ₃₂₃₁ = Γ[𝐦]
plot!(Γ₁,markersize=1, aspect_ratio=1)
plot!(Γ₃₂₃₁,markersize=1.5, aspect_ratio=1)
Example block output

Measures

We now consider a measure $\mu$ supported on a fractal attractor $\Gamma$. This is necessary to define integrals and integral equations on $\Gamma$. For an attractor defined with $M$ similarities, an invariant measure $\mu$ is defined by an associated set of probabilities $p_1,\ldots,p_M$ satisfying $\sum_{m=1}^M p_m =1$, such that

\[\mu(\Gamma_\mathbf{m}) = \left(\prod_{i=1}^\ell p_{m_i}\right)\mu(\Gamma).\]

FractalIntegrals.InvariantMeasureType
InvariantMeasure{N, M, T, A <: AbstractAttractor{N, M, T}}

A general class of measure which can be defined supported on an attractor. Defined by a 'support', which is an attractor, and a vector of probability weights, invariant measures satisfy a 'balance' condition.

Fields

  • supp: The attractor on which the measure is supported
  • suppmeasure: The measure of the support
  • weights: A vector of probability weights
source

The Hausdorff Measure $\mathcal{H}^d$ is a special case of an Invariant Measure, where $p_m=\rho_m^d$ for $m=1,\ldots,M$. This ensures that the mass of the measure is, in some sense, spread evenly across $\Gamma$. A useful consequence is that if $\Gamma$ is invariant under any non-trivial rotations/reflections, then this is inherited by the Hausdorff measure.

FractalIntegrals.HausdorffMeasureType
HausdorffMeasure{N, M, T, A <: AbstractAttractor{N, M, T}}

A special case of InvariantMeasure where the contraction factors ρm and the probability weights pm satisfy ρm^d=pm, where d is the Hausdorff dimension of the attractor.

source
Note

Precise values of the Hausdorff measure of many well-known fractals remains an open problem. Many Cantor-like sets with $d\leq1$ are known to have a Hausdorff measure of one. However, if $\Gamma$ is the Sierpinski triangle, the best estimate is (to four digits) [1]

\[0.5631 \leq \mathcal{H}^d(\Gamma) \leq 0.8179.\]

Therefore, our definition of the Hausdorff measure is slightly generalised to $\mu = C\mathcal{H}^d$ for some constant $C$. If the field suppmeasure is not provided when defining the measure, this defaults to one, equivalent $\mu$ is scaled so that $\mu(\Gamma) = 1$. As will be discussed in the next section, for many applications, this choice is insignificant.

The Hausdorff measure is the most natural measure for any fractal, and is used by default throughout FractalIntegrals. Recall that from an above example, $\Gamma$ represents the Sierpinski triangle.

# no weights specified
𝓗ᵈ = InvariantMeasure(Γ)
print(typeof(𝓗ᵈ))
HausdorffMeasure{2, 3, Float64, FractalIntegrals.HomogenousAttractor{2, 3, Float64}}

Sub-measures

A sub-measure is analogous to the definition of sub-attractor, and can be easily constructed using vector indices.

For some measure $\mu:\Gamma\to [0,\infty)$, it is the restriction $\mu_{\mathbf{m}}:=\mu|_{\Gamma_{\mathbf{m}}}$. It is mentioned in the above section that the field suppmeasure is difficult to estimate, but here it is computed automatically from $\mu$, via the identity

\[\mu_\mathbf{m}(\Gamma_{\mathbf{m}}) = \mu(s_{\mathbf{m}}(\Gamma)).\]

Plotting measures

When plot is used on an InvariantMeasure, colouring is used to represent the distribution of mass.

# create random set of probabilites
𝐩 = rand(3)
𝐩 = 𝐩/sum(𝐩)
μ = InvariantMeasure(Γ, 𝐩)
plot(μ, markersize = 1)
Example block output
Measure
├── AbstractInvariantMeasure
│   ├── InvariantMeasure
│   ├── HausdorffMeasure
├── MeasureUnion