This animation uses the modular flow to produce a periodic family of quasi-periodic functions. Since the family is periodic, we get a looping animation by visualizing with domain coloring. This is also explained in my paper "Looping animations using the modular flow and elliptic functions."
ABSTRACT (original article): This paper describes an approach to generating looping animations using the modular flow and elliptic functions. The modular flow is a flow on lattices with many periodic orbits, and elliptic functions are meromorphic, doubly-periodic functions which can be visualized using domain coloring. CITATION (original article): Clayton Shonkwiler (2026), Looping Animations Using the Modular Flow and Elliptic Functions, Proceedings of Bridges 2026: Mathematics and the Arts, 533--536. http://archive.bridgesmathart.org/2026/bridges2026-533.html
The Modular Flow
The Modular Flow
See the links which include the phrase “modular flow” in the previous paragraph for more, but for the modular flow the idea is that we will let act on by . As an action on the plane, this is very far from being periodic, but we can also think of the induced action on lattices , and if we choose and carefully, the resulting orbit will be periodic; that is, there will exist ≠0 so that ·Λ=Λ.
2
t·(x,y):=(x,y)
t
-t
Λ={m+n:m,n∈}
u
1
u
2
u
1
u
2
t
0
t
0
To figure out some for which this works, let’s turn this into a matrix problem. Let be the matrix with columns and . Then the lattice will be generated by the columns of
U. On the other hand, if is an integer matrix, then the columns of will be integer linear combinations of and ; that is, elements of . So we might hope that the columns of
U will be the columns of . Moreover, , so the action on is area-preserving, and we can only hope for this to work if as well.
Λ
U
22
u
1
u
2
t·Λ
t | 0 |
0 | -t |
B=
a | b |
c | d |
UB
u
1
u
2
Λ
t 0 | 0 |
0 | - t 0 |
UB
det
=1
t | 0 |
0 | -t |
2
detB=1
In other words, if we’re looking for a periodic lattice, we can try to solve the equation for and , where is our favorite matrix with determinant 1.
UB=
U
t 0 | 0 |
0 | - t 0 |
U
t
0
B
22
Taking the transpose of both sides, we see that the rows of must be eigenvectors of with corresponding eigenvalues . So for example when we have:
U
T
B
±
t
0
B=
2 | 1 |
1 | 1 |
In[]:=
Eigensystem[{{2,1},{1,1}}]
Out[]=
(3+(3-(1+(1-
1
2
5
),1
2
5
),1
2
5
),1,1
2
5
),1That is, =
, =
, and =ln(1+ϕ), where is the golden ratio. In fact, I could just as well scale by to get the more pleasing . Let’s visualize this and see that it really is periodic:
u
1
ϕ |
1 |
u
2
-1/ϕ |
1 |
t
0
ϕ=
1+
5
2
u
2
-ϕ
U=
ϕ | 1 |
1 | -ϕ |
In[]:=
DynamicModule[{M,pts,U={{GoldenRatio,1},{-1,GoldenRatio}}},pts=Flatten[Table[{x,y},{x,-15,15},{y,-15,15}],1];Animate[M=DiagonalMatrix[{,}].U;Graphics[{Thickness[.005],PointSize[Large],Point[M.#]&/@pts},PlotRange->10],{s,0,Log[1+GoldenRatio]},SaveDefinitions->True,AnimationRunning->False]]
s
E
-s
E
Out[]=
A Quasiperiodic Function
A Quasiperiodic Function
Now, think of the lattice as living in rather than in . That is, we now think of where ,∈. And, for any such lattice we can think about doubly-periodic functions with periods and ; that is, functions so that , which of course implies for all . If such an is meromorphic then it is usually called an elliptic function.
Λ
2
Λ={m+n:m,n∈}
ω
1
ω
2
ω
1
ω
2
ω
1
ω
2
f:
f(z+)=f(z)=f(z+)
ω
1
ω
2
f(z+m+n)=f(z)
ω
1
ω
2
m,n∈
f
This is the idea behind the animation Phase, where I applied this idea to the most basic elliptic function, the Weierstrass -function. Since this function depends on the lattice , I like to write it as (z), though it’s more common to write or , where , are the Weierstrass invariants of , and indeed this latter is how Mathematica works. In the below code, I translate back and forth between and using the built-in Mathematica function WeierstrassInvariants.
℘
Λ
℘
Λ
℘(p;,)
ω
1
ω
2
℘(z;,)
g
2
g
3
g
2
g
3
Λ
(,)
ω
1
ω
2
(,)
g
2
g
3
In any case, the point is that if we have a periodic family of lattices, then the corresponding family is also periodic (and likewise for any other elliptic function), and so produces a looping animation when visualized.
t·Λ
℘
t·Λ
Here I’m going to apply the same idea to a quasiperiodic function, namely the Weierstrass function, which is implicitly defined by ln()=-. This function is entire and can be used to represent all elliptic functions by way of their zeros and poles. Plus, it looks weird and interesting:
2
d
d
2
z
σ
Λ
℘
Λ
In[]:=
ComplexPlot[WeierstrassSigma[z,WeierstrassInvariants[{1,I}]],{z,10}]
Out[]=
Putting it all together, we’re going to let be the lattice generated by and (or, in complex terms, and ), we’re going to let be its periodic orbit under the modular flow (with period =ln(1+ϕ)), and we’re going to build the corresponding periodic family of quasiperiodic functions , which we’ll visualize and turn into a looping animation using domain coloring.
Λ
ϕ |
1 |
1 |
-ϕ |
ϕ+
1-ϕ
t·Λ
t
0
σ
t·Λ
In[]:=
cols={,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,};
To get the look I wanted, I rotated this palette a quarter-turn, which explains the Mod[#8 - 1/4, 1] in the code, which I can now give:
quasi=Module{g2,g3,U={{GoldenRatio,1},{1,-GoldenRatio}}},ParallelTable{g2,g3}=WeierstrassInvariants[N[Complex@@(DiagonalMatrix[{,}].U.#)]&/@{{1,0},{0,1}}];ComplexPlotWeierstrassSigma[z,{g2,g3}],{z,20},ColorFunction{Blend[cols,Mod[#8-1/4,1]]&,None},,{s,0.,Log[1+GoldenRatio]-#,#}&[Log[1+GoldenRatio]/70.];
s
E
-s
E
Which we can export to a GIF:
Export[NotebookDirectory[]<>"quasi.gif",quasi,"AnimationRepetitions"->Infinity,"DisplayDurations"->1/50];
Or visualize using ListAnimate:
In[]:=
ListAnimate[sigmaframes,50]
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
Quasi (periodic family of quasiperiodic functions)
by Clayton Shonkwiler
Wolfram Community, STAFF PICKS, June 15, 2026
https://community.wolfram.com/groups/-/m/t/3734174
by Clayton Shonkwiler
Wolfram Community, STAFF PICKS, June 15, 2026
https://community.wolfram.com/groups/-/m/t/3734174