How can I plot a Farey diagram?How to make this beautiful animationPlotting an epicycloidGenerating a topological space diagram for an n-element setMathematica code for Bifurcation DiagramHow to draw a contour diagram in Mathematica?How to draw timing diagram from a list of values?Expressing a series formulaBifurcation diagram for Piecewise functionHow to draw a clock-diagram?How can I plot a space time diagram in mathematica?Plotting classical polymer modelA problem in bifurcation diagram
Denied boarding due to overcrowding, Sparpreis ticket. What are my rights?
Is ipsum/ipsa/ipse a third person pronoun, or can it serve other functions?
Landlord wants to switch my lease to a "Land contract" to "get back at the city"
Are cabin dividers used to "hide" the flex of the airplane?
What is GPS' 19 year rollover and does it present a cybersecurity issue?
Can I legally use front facing blue light in the UK?
What is the offset in a seaplane's hull?
Ideas for 3rd eye abilities
Why did the Germans forbid the possession of pet pigeons in Rostov-on-Don in 1941?
Does the average primeness of natural numbers tend to zero?
What to wear for invited talk in Canada
What does "enim et" mean?
"listening to me about as much as you're listening to this pole here"
Lied on resume at previous job
Is there a way to make member function NOT callable from constructor?
What is the command to reset a PC without deleting any files
Is it wise to hold on to stock that has plummeted and then stabilized?
What are the advantages and disadvantages of running one shots compared to campaigns?
Where to refill my bottle in India?
What does 'script /dev/null' do?
I see my dog run
Why do we use polarized capacitors?
How to move the player while also allowing forces to affect it
Shall I use personal or official e-mail account when registering to external websites for work purpose?
How can I plot a Farey diagram?
How to make this beautiful animationPlotting an epicycloidGenerating a topological space diagram for an n-element setMathematica code for Bifurcation DiagramHow to draw a contour diagram in Mathematica?How to draw timing diagram from a list of values?Expressing a series formulaBifurcation diagram for Piecewise functionHow to draw a clock-diagram?How can I plot a space time diagram in mathematica?Plotting classical polymer modelA problem in bifurcation diagram
$begingroup$
How can I plot the following diagram for a Farey series?
graphics number-theory
New contributor
$endgroup$
add a comment |
$begingroup$
How can I plot the following diagram for a Farey series?
graphics number-theory
New contributor
$endgroup$
$begingroup$
From the beautiful book A. Hatcher Topology of numbers
$endgroup$
– Gustavo Rubiano
7 hours ago
$begingroup$
Could you perhaps expand a bit on how the curves are calculated etc?
$endgroup$
– MarcoB
6 hours ago
$begingroup$
pi.math.cornell.edu/~hatcher/TN/TNch1.pdf
$endgroup$
– Moo
5 hours ago
add a comment |
$begingroup$
How can I plot the following diagram for a Farey series?
graphics number-theory
New contributor
$endgroup$
How can I plot the following diagram for a Farey series?
graphics number-theory
graphics number-theory
New contributor
New contributor
edited 1 hour ago
Michael E2
150k12203482
150k12203482
New contributor
asked 7 hours ago
Gustavo RubianoGustavo Rubiano
113
113
New contributor
New contributor
$begingroup$
From the beautiful book A. Hatcher Topology of numbers
$endgroup$
– Gustavo Rubiano
7 hours ago
$begingroup$
Could you perhaps expand a bit on how the curves are calculated etc?
$endgroup$
– MarcoB
6 hours ago
$begingroup$
pi.math.cornell.edu/~hatcher/TN/TNch1.pdf
$endgroup$
– Moo
5 hours ago
add a comment |
$begingroup$
From the beautiful book A. Hatcher Topology of numbers
$endgroup$
– Gustavo Rubiano
7 hours ago
$begingroup$
Could you perhaps expand a bit on how the curves are calculated etc?
$endgroup$
– MarcoB
6 hours ago
$begingroup$
pi.math.cornell.edu/~hatcher/TN/TNch1.pdf
$endgroup$
– Moo
5 hours ago
$begingroup$
From the beautiful book A. Hatcher Topology of numbers
$endgroup$
– Gustavo Rubiano
7 hours ago
$begingroup$
From the beautiful book A. Hatcher Topology of numbers
$endgroup$
– Gustavo Rubiano
7 hours ago
$begingroup$
Could you perhaps expand a bit on how the curves are calculated etc?
$endgroup$
– MarcoB
6 hours ago
$begingroup$
Could you perhaps expand a bit on how the curves are calculated etc?
$endgroup$
– MarcoB
6 hours ago
$begingroup$
pi.math.cornell.edu/~hatcher/TN/TNch1.pdf
$endgroup$
– Moo
5 hours ago
$begingroup$
pi.math.cornell.edu/~hatcher/TN/TNch1.pdf
$endgroup$
– Moo
5 hours ago
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
The curvilinear triangles which are characteristic for this type of plot are called hypocyloid curves. We can use the parametric equations on Wikipedia to plot these, like so:
x[a_, b_, t_] := (b - a) Cos[t] + a Cos[(b - a)/a t]
y[a_, b_, t_] := (b - a) Sin[t] - a Sin[(b - a)/a t]
hypocycloid[n_] := ParametricPlot[
x[1/n, 1, t], y[1/n, 1, t],
t, 0, 2 Pi,
PlotStyle -> Thickness[0.002], Black
]
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
ImageSize -> 500
]
I've previously written about an application of hypocycloids here, and I showed how to visualize epicycloids here.
How to generate the labels is described here (also linked to by moo in a comment). I will simply provide the code.
mediant[a_, b_, c_, d_] := a + c, b + d
recursive[v1_, v2_, depth_] := If[
depth > 2,
mediant[v1, v2],
recursive[v1, mediant[v1, v2], depth + 1],
mediant[v1, v2],
recursive[mediant[v1, v2], v2, depth + 1]
]
computeLabels[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["``/``"] @@@ numbers
]
computeLabelsNegative[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["-`2`/`1`"] @@@ numbers
]
labels = Reverse@Join[
"1/0",
computeLabels[1, 0, 1, 1],
"1/1",
computeLabels[1, 1, 0, 1],
"0/1",
computeLabelsNegative[1, 0, 1, 1],
"-1,1",
computeLabelsNegative[1, 1, 0, 1]
];
coords = CirclePoints[1.1, 186 Degree, 64];
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
Graphics@MapThread[Text, labels, coords],
ImageSize -> 500
]
$endgroup$
add a comment |
$begingroup$
I looked up the Farey sequence on Wikipedia, out of curiosity, because I had not heard of it before. The Farey sequence of order $n$ is "the sequence of completely reduced fractions between 0 and 1 which, when in lowest terms, have denominators less than or equal to $n$, arranged in order of increasing size".
On that basis, you can generate the sequence as follows, for instance:
ClearAll[farey]
farey[n_Integer] := (Divide @@@ Subsets[Range[n], 2]) ~ Join ~ 0, 1 //DeleteDuplicates //Sort
So for instance:
farey[5]
0, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 1
I am not sure how these sequences are connected with the figure you showed though.
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
);
);
, "mathjax-editing");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "387"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Gustavo Rubiano is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f194838%2fhow-can-i-plot-a-farey-diagram%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
The curvilinear triangles which are characteristic for this type of plot are called hypocyloid curves. We can use the parametric equations on Wikipedia to plot these, like so:
x[a_, b_, t_] := (b - a) Cos[t] + a Cos[(b - a)/a t]
y[a_, b_, t_] := (b - a) Sin[t] - a Sin[(b - a)/a t]
hypocycloid[n_] := ParametricPlot[
x[1/n, 1, t], y[1/n, 1, t],
t, 0, 2 Pi,
PlotStyle -> Thickness[0.002], Black
]
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
ImageSize -> 500
]
I've previously written about an application of hypocycloids here, and I showed how to visualize epicycloids here.
How to generate the labels is described here (also linked to by moo in a comment). I will simply provide the code.
mediant[a_, b_, c_, d_] := a + c, b + d
recursive[v1_, v2_, depth_] := If[
depth > 2,
mediant[v1, v2],
recursive[v1, mediant[v1, v2], depth + 1],
mediant[v1, v2],
recursive[mediant[v1, v2], v2, depth + 1]
]
computeLabels[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["``/``"] @@@ numbers
]
computeLabelsNegative[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["-`2`/`1`"] @@@ numbers
]
labels = Reverse@Join[
"1/0",
computeLabels[1, 0, 1, 1],
"1/1",
computeLabels[1, 1, 0, 1],
"0/1",
computeLabelsNegative[1, 0, 1, 1],
"-1,1",
computeLabelsNegative[1, 1, 0, 1]
];
coords = CirclePoints[1.1, 186 Degree, 64];
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
Graphics@MapThread[Text, labels, coords],
ImageSize -> 500
]
$endgroup$
add a comment |
$begingroup$
The curvilinear triangles which are characteristic for this type of plot are called hypocyloid curves. We can use the parametric equations on Wikipedia to plot these, like so:
x[a_, b_, t_] := (b - a) Cos[t] + a Cos[(b - a)/a t]
y[a_, b_, t_] := (b - a) Sin[t] - a Sin[(b - a)/a t]
hypocycloid[n_] := ParametricPlot[
x[1/n, 1, t], y[1/n, 1, t],
t, 0, 2 Pi,
PlotStyle -> Thickness[0.002], Black
]
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
ImageSize -> 500
]
I've previously written about an application of hypocycloids here, and I showed how to visualize epicycloids here.
How to generate the labels is described here (also linked to by moo in a comment). I will simply provide the code.
mediant[a_, b_, c_, d_] := a + c, b + d
recursive[v1_, v2_, depth_] := If[
depth > 2,
mediant[v1, v2],
recursive[v1, mediant[v1, v2], depth + 1],
mediant[v1, v2],
recursive[mediant[v1, v2], v2, depth + 1]
]
computeLabels[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["``/``"] @@@ numbers
]
computeLabelsNegative[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["-`2`/`1`"] @@@ numbers
]
labels = Reverse@Join[
"1/0",
computeLabels[1, 0, 1, 1],
"1/1",
computeLabels[1, 1, 0, 1],
"0/1",
computeLabelsNegative[1, 0, 1, 1],
"-1,1",
computeLabelsNegative[1, 1, 0, 1]
];
coords = CirclePoints[1.1, 186 Degree, 64];
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
Graphics@MapThread[Text, labels, coords],
ImageSize -> 500
]
$endgroup$
add a comment |
$begingroup$
The curvilinear triangles which are characteristic for this type of plot are called hypocyloid curves. We can use the parametric equations on Wikipedia to plot these, like so:
x[a_, b_, t_] := (b - a) Cos[t] + a Cos[(b - a)/a t]
y[a_, b_, t_] := (b - a) Sin[t] - a Sin[(b - a)/a t]
hypocycloid[n_] := ParametricPlot[
x[1/n, 1, t], y[1/n, 1, t],
t, 0, 2 Pi,
PlotStyle -> Thickness[0.002], Black
]
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
ImageSize -> 500
]
I've previously written about an application of hypocycloids here, and I showed how to visualize epicycloids here.
How to generate the labels is described here (also linked to by moo in a comment). I will simply provide the code.
mediant[a_, b_, c_, d_] := a + c, b + d
recursive[v1_, v2_, depth_] := If[
depth > 2,
mediant[v1, v2],
recursive[v1, mediant[v1, v2], depth + 1],
mediant[v1, v2],
recursive[mediant[v1, v2], v2, depth + 1]
]
computeLabels[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["``/``"] @@@ numbers
]
computeLabelsNegative[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["-`2`/`1`"] @@@ numbers
]
labels = Reverse@Join[
"1/0",
computeLabels[1, 0, 1, 1],
"1/1",
computeLabels[1, 1, 0, 1],
"0/1",
computeLabelsNegative[1, 0, 1, 1],
"-1,1",
computeLabelsNegative[1, 1, 0, 1]
];
coords = CirclePoints[1.1, 186 Degree, 64];
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
Graphics@MapThread[Text, labels, coords],
ImageSize -> 500
]
$endgroup$
The curvilinear triangles which are characteristic for this type of plot are called hypocyloid curves. We can use the parametric equations on Wikipedia to plot these, like so:
x[a_, b_, t_] := (b - a) Cos[t] + a Cos[(b - a)/a t]
y[a_, b_, t_] := (b - a) Sin[t] - a Sin[(b - a)/a t]
hypocycloid[n_] := ParametricPlot[
x[1/n, 1, t], y[1/n, 1, t],
t, 0, 2 Pi,
PlotStyle -> Thickness[0.002], Black
]
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
ImageSize -> 500
]
I've previously written about an application of hypocycloids here, and I showed how to visualize epicycloids here.
How to generate the labels is described here (also linked to by moo in a comment). I will simply provide the code.
mediant[a_, b_, c_, d_] := a + c, b + d
recursive[v1_, v2_, depth_] := If[
depth > 2,
mediant[v1, v2],
recursive[v1, mediant[v1, v2], depth + 1],
mediant[v1, v2],
recursive[mediant[v1, v2], v2, depth + 1]
]
computeLabels[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["``/``"] @@@ numbers
]
computeLabelsNegative[v1_, v2_] := Module[numbers,
numbers =
Cases[recursive[v1, v2, 0], _Integer, _Integer, Infinity];
StringTemplate["-`2`/`1`"] @@@ numbers
]
labels = Reverse@Join[
"1/0",
computeLabels[1, 0, 1, 1],
"1/1",
computeLabels[1, 1, 0, 1],
"0/1",
computeLabelsNegative[1, 0, 1, 1],
"-1,1",
computeLabelsNegative[1, 1, 0, 1]
];
coords = CirclePoints[1.1, 186 Degree, 64];
Show[
Graphics[Circle[0, 0, 1]],
hypocycloid[2],
hypocycloid[4],
hypocycloid[8],
hypocycloid[16],
hypocycloid[32],
hypocycloid[64],
Graphics@MapThread[Text, labels, coords],
ImageSize -> 500
]
edited 50 mins ago
answered 1 hour ago
C. E.C. E.
51.1k3101206
51.1k3101206
add a comment |
add a comment |
$begingroup$
I looked up the Farey sequence on Wikipedia, out of curiosity, because I had not heard of it before. The Farey sequence of order $n$ is "the sequence of completely reduced fractions between 0 and 1 which, when in lowest terms, have denominators less than or equal to $n$, arranged in order of increasing size".
On that basis, you can generate the sequence as follows, for instance:
ClearAll[farey]
farey[n_Integer] := (Divide @@@ Subsets[Range[n], 2]) ~ Join ~ 0, 1 //DeleteDuplicates //Sort
So for instance:
farey[5]
0, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 1
I am not sure how these sequences are connected with the figure you showed though.
$endgroup$
add a comment |
$begingroup$
I looked up the Farey sequence on Wikipedia, out of curiosity, because I had not heard of it before. The Farey sequence of order $n$ is "the sequence of completely reduced fractions between 0 and 1 which, when in lowest terms, have denominators less than or equal to $n$, arranged in order of increasing size".
On that basis, you can generate the sequence as follows, for instance:
ClearAll[farey]
farey[n_Integer] := (Divide @@@ Subsets[Range[n], 2]) ~ Join ~ 0, 1 //DeleteDuplicates //Sort
So for instance:
farey[5]
0, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 1
I am not sure how these sequences are connected with the figure you showed though.
$endgroup$
add a comment |
$begingroup$
I looked up the Farey sequence on Wikipedia, out of curiosity, because I had not heard of it before. The Farey sequence of order $n$ is "the sequence of completely reduced fractions between 0 and 1 which, when in lowest terms, have denominators less than or equal to $n$, arranged in order of increasing size".
On that basis, you can generate the sequence as follows, for instance:
ClearAll[farey]
farey[n_Integer] := (Divide @@@ Subsets[Range[n], 2]) ~ Join ~ 0, 1 //DeleteDuplicates //Sort
So for instance:
farey[5]
0, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 1
I am not sure how these sequences are connected with the figure you showed though.
$endgroup$
I looked up the Farey sequence on Wikipedia, out of curiosity, because I had not heard of it before. The Farey sequence of order $n$ is "the sequence of completely reduced fractions between 0 and 1 which, when in lowest terms, have denominators less than or equal to $n$, arranged in order of increasing size".
On that basis, you can generate the sequence as follows, for instance:
ClearAll[farey]
farey[n_Integer] := (Divide @@@ Subsets[Range[n], 2]) ~ Join ~ 0, 1 //DeleteDuplicates //Sort
So for instance:
farey[5]
0, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 1
I am not sure how these sequences are connected with the figure you showed though.
answered 6 hours ago
MarcoBMarcoB
38.6k557115
38.6k557115
add a comment |
add a comment |
Gustavo Rubiano is a new contributor. Be nice, and check out our Code of Conduct.
Gustavo Rubiano is a new contributor. Be nice, and check out our Code of Conduct.
Gustavo Rubiano is a new contributor. Be nice, and check out our Code of Conduct.
Gustavo Rubiano is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Mathematica Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f194838%2fhow-can-i-plot-a-farey-diagram%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
From the beautiful book A. Hatcher Topology of numbers
$endgroup$
– Gustavo Rubiano
7 hours ago
$begingroup$
Could you perhaps expand a bit on how the curves are calculated etc?
$endgroup$
– MarcoB
6 hours ago
$begingroup$
pi.math.cornell.edu/~hatcher/TN/TNch1.pdf
$endgroup$
– Moo
5 hours ago