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.Similarity
— TypeSimilarity{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)
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.Attractor
— TypeAttractor{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 attractorM
is the number of similaritiesT<:Number
is the numeric type
Fields
ifs::SVector{M, Similarity{N, T}}
: iterated function systemdiam::T
: diamter of attractord::T
: Hausdorff dimension of attractorconnectedness::Matrix{Bool}
: matrix describing connected subcomponentssymmetries::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.
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)
Presets
You can create your own attractor from scratch, as explained above. But a range of preset attractors are available.
FractalIntegrals.getfractal
— Functiongetfractal(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 Setcantordust
: Cantor Dustsierpinskitriangle
: Sierpinski Trianglevicsek
: Vicsek Fractalkochcurve
: Koch Curvesierpinskicarpet
: Sierpinski Carpetheighwaydragon
: Heighway Dragonkochsnowflake
: 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)
Γ = getfractal("sierpinskitriangle")
plot(Γ, aspect_ratio=1)
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)
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.InvariantMeasure
— TypeInvariantMeasure{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 supportedsuppmeasure
: The measure of the supportweights
: A vector of probability weights
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.HausdorffMeasure
— TypeHausdorffMeasure{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.
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)
Measure
├── AbstractInvariantMeasure
│ ├── InvariantMeasure
│ ├── HausdorffMeasure
├── MeasureUnion