Bossy Lobsterhttps://blog.bossylobster.com/2024-02-29T00:00:00-08:00A blog by Danny Hermes; musing on tech, mathematics, etc.The missing type in the Go standard library: Date!2024-02-29T00:00:00-08:002024-02-29T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2024-02-29:/2024/02/date-the-missing-type.html<div style="text-align: center;">
<p><img alt=go-date src="/images/calendar-pins.jpg"></p>
</div>
<blockquote>
<p>This is cross-posted from the Hardfin engineering <a href="https://engineering.hardfin.com/2024/02/date-the-missing-type/">blog</a>.</p>
</blockquote>
<p>The Go standard library uses a single overloaded <a href="https://pkg.go.dev/time#Time">type</a> as a stand-in for
both full datetimes<sup id=sf-date-the-missing-type-1-back><a href=#sf-date-the-missing-type-1 class=simple-footnote title="Here by datetime, we mean an object that contains both date (year, month, day), time information (hour, minute, second, millisecond / microsecond / nanosecond), and often a relevant timezone as well. For example this is provided by the datetime.datetime type in Python and Date in JavaScript.">1</a></sup> and dates. This mostly "just works", but slowly
starts to <strong>degrade correctness</strong> in codebases where both datetime and date
values need to <a href=#opportunity-for-correctness-to-degrade>interact</a>.</p>
<p>We store …</p><div style="text-align: center;">
<p><img alt=go-date src="/images/calendar-pins.jpg"></p>
</div>
<blockquote>
<p>This is cross-posted from the Hardfin engineering <a href="https://engineering.hardfin.com/2024/02/date-the-missing-type/">blog</a>.</p>
</blockquote>
<p>The Go standard library uses a single overloaded <a href="https://pkg.go.dev/time#Time">type</a> as a stand-in for
both full datetimes<sup id=sf-date-the-missing-type-1-back><a href=#sf-date-the-missing-type-1 class=simple-footnote title="Here by datetime, we mean an object that contains both date (year, month, day), time information (hour, minute, second, millisecond / microsecond / nanosecond), and often a relevant timezone as well. For example this is provided by the datetime.datetime type in Python and Date in JavaScript.">1</a></sup> and dates. This mostly "just works", but slowly
starts to <strong>degrade correctness</strong> in codebases where both datetime and date
values need to <a href=#opportunity-for-correctness-to-degrade>interact</a>.</p>
<p>We store events using a mix of datetime and date <a href="https://www.postgresql.org/docs/16/datatype-datetime.html">columns</a> in our database
(depending on the type of event). Having a mix of datetimes and date values
became a persistent source of subtle confusion and extended discussion<sup id=sf-date-the-missing-type-2-back><a href=#sf-date-the-missing-type-2 class=simple-footnote title='Those discussions usually included a phrase like "I wish the Go standard library had a separate Date type"!'>2</a></sup> within our engineering team. As a result, we
created a simple <code>Date</code> type that organically grew until it could replace all of
our existing usage of <code>time.Time</code>.</p>
<p>The <code>go-date</code> <a href="https://pkg.go.dev/github.com/hardfinhq/go-date">package</a> is here to fill the gap left by the Go standard
library!</p>
<blockquote>
<p>Having a mix of datetimes and date values became a persistent source of subtle
confusion and extended discussion within our engineering team</p>
</blockquote>
<h2 id=opportunity-for-correctness-to-degrade>Opportunity for correctness to degrade</h2>
<p>To understand an example where correctness can start to degrade, consider
a datetime value (<code>now</code>) and a date value (<code>deadline</code>):</p>
<div class=highlight><pre><span></span><code><span class=nx>now</span> <span class=o>:=</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Now</span><span class=p>()</span>
<span class=c1>// Common convention for date values is to use a `time.Time` with</span>
<span class=c1>// only the year, month, and day set. For example, this convention</span>
<span class=c1>// is followed by the standard library when a timestamp of the form</span>
<span class=c1>// YYYY-MM-DD is parsed via `time.Parse(time.DateOnly, value)`.</span>
<span class=nx>deadline</span> <span class=o>:=</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Date</span><span class=p>(</span><span class=mi>2024</span><span class=p>,</span> <span class=nx>time</span><span class=p>.</span><span class=nx>March</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=nx>time</span><span class=p>.</span><span class=nx>UTC</span><span class=p>)</span>
</code></pre></div>
<p>With two <code>time.Time</code> values, it's very reasonable for a developer to
compute the check "current date is on or before the deadline" via:</p>
<div class=highlight><pre><span></span><code><span class=nx>withinDeadline</span> <span class=o>:=</span> <span class=p>!</span><span class=nx>now</span><span class=p>.</span><span class=nx>After</span><span class=p>(</span><span class=nx>deadline</span><span class=p>)</span>
</code></pre></div>
<p>However, this is problematic for at least two reasons. First and foremost, the
timestamp of <code>deadline</code> is <code>00:00</code>, so it leaves out virtually 100% of the
deadline day. Secondly, the concept of "today" depends<sup id=sf-date-the-missing-type-3-back><a href=#sf-date-the-missing-type-3 class=simple-footnote title="Why does the "today" depend on the timezone? If a friend from Los Angeles calls at 11pm, but you're in New York, today is tomorrow! (Or yesterday, depending on who says it.)">3</a></sup>
on the <strong>timezone</strong> and for many applications, the application user likely has a
specific timezone that is natural for that check.</p>
<p>In codebases maintained over time by teams of different people, it's very
common for a developer to come in and edit existing code that they didn't
write. In cases like this, it's easy to have less context than the original
author.</p>
<p>Without sufficient context, mixing up the precision of <code>now</code> (datetime) and the
precision of <code>deadline</code> (date) is an easy mistake to make. On the other hand, if
<code>deadline</code> was not the same type as <code>now</code>, developers are forced to consider the
difference between the two types and account for this difference. If a <code>Date</code>
was used to represent the deadline instead:</p>
<div class=highlight><pre><span></span><code><span class=nx>deadlineDate</span> <span class=o>:=</span> <span class=nx>date</span><span class=p>.</span><span class=nx>NewDate</span><span class=p>(</span><span class=mi>2024</span><span class=p>,</span> <span class=nx>time</span><span class=p>.</span><span class=nx>March</span><span class=p>,</span> <span class=mi>1</span><span class=p>)</span>
</code></pre></div>
<p>then a correct implementation can both incorporate the timezone and ensure
that same percentage of the hours in the day are not erroneously ignored:</p>
<div class=highlight><pre><span></span><code><span class=nx>nowDate</span> <span class=o>:=</span> <span class=nx>date</span><span class=p>.</span><span class=nx>InTimezone</span><span class=p>(</span><span class=nx>now</span><span class=p>,</span> <span class=nx>tz</span><span class=p>)</span>
<span class=nx>withinDeadline</span> <span class=o>:=</span> <span class=p>!</span><span class=nx>nowDate</span><span class=p>.</span><span class=nx>After</span><span class=p>(</span><span class=nx>deadlineDate</span><span class=p>)</span>
</code></pre></div>
<div style="text-align: center;">
<p><img alt="Missing pieces" src="/images/puzzle-missing-pieces.jpg"></p>
</div>
<h2>Integrating with sqlc</h2>
<p>We use the <code>sqlc</code> <a href="https://docs.sqlc.dev">library</a> at Hardfin for all Go code that interacts with
the database. (See the wonderful <a href="https://brandur.org/sqlc">post</a> by PostgreSQL blogging legend Brandur
Leach for some of the benefits of <code>sqlc</code>.)</p>
<p>Out of the box, <code>sqlc</code> uses a Go <code>time.Time</code> both for columns of type
<code>TIMESTAMPTZ</code> and <code>DATE</code>. When reading <code>DATE</code> values (which come over the
wire in the form YYYY-MM-DD), the Go standard library produces values of the
form:</p>
<div class=highlight><pre><span></span><code><span class=nx>time</span><span class=p>.</span><span class=nx>Date</span><span class=p>(</span><span class=nx>YYYY</span><span class=p>,</span> <span class=nx>MM</span><span class=p>,</span> <span class=nx>DD</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=nx>time</span><span class=p>.</span><span class=nx>UTC</span><span class=p>)</span>
</code></pre></div>
<p>Instead, we can instruct <code>sqlc</code> to <strong>globally</strong> use <code>date.Date</code> and
<code>date.NullDate</code> when parsing <code>DATE</code> columns:</p>
<div class=highlight><pre><span></span><code><span class=nn>---</span>
<span class=nt>version</span><span class=p>:</span> <span class=s>"2"</span>
<span class=nt>overrides</span><span class=p>:</span>
<span class=nt>go</span><span class=p>:</span>
<span class=nt>overrides</span><span class=p>:</span>
<span class="p p-Indicator">-</span> <span class=nt>go_type</span><span class=p>:</span>
<span class=nt>import</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">github.com/hardfinhq/go-date</span>
<span class=nt>package</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">date</span>
<span class=nt>type</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">NullDate</span>
<span class=nt>db_type</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">date</span>
<span class=nt>nullable</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="p p-Indicator">-</span> <span class=nt>go_type</span><span class=p>:</span>
<span class=nt>import</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">github.com/hardfinhq/go-date</span>
<span class=nt>package</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">date</span>
<span class=nt>type</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">Date</span>
<span class=nt>db_type</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">date</span>
<span class=nt>nullable</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">false</span>
</code></pre></div>
<h2>Why do <em>we</em> care?</h2>
<p>At Hardfin, we help equipment manufacturers automate their financial operations
by connecting real world <strong>events</strong> to hardware subscriptions. This inherently
means we collect and store <strong>a lot</strong> of dates.</p>
<p>For many event types, we are able to collect both the date and the timestamp.
For example, if a user action occurs in our application or if an update comes in
from a third party system like Stripe. However for some events, the timestamp is
not required, not important, and oftentimes not known. For example, an operator
may know that "a robot was shipped on December 28" but may not know the exact
time of day that robot was shipped. The date December 28 has enough information
<strong>without the timestamp</strong> to trigger automation for the manufacturer's billing
and revenue.</p>
<div style="text-align: center;">
<p><img alt="Connecting events" src="/images/train-aerial-view.jpg"></p>
</div>
<h2>Go forth and differentiate</h2>
<p>This package is intended to be <strong>simple</strong>! (Simple to understand and simple to
implement.) The package is only intended to cover "modern" dates (i.e. dates
between the years 1900 and 2100) and so it can avoid resorting to the
<a href="https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar">proleptic Gregorian calendar</a>.</p>
<p>As a result, the core <code>Date</code> type directly exposes the year, month, and day as
struct fields.</p>
<p>We hope this package will come in handy for teams that need to draw a clear
distinction between datetime and date values!</p>
<div style="text-align: center;">
<p><img alt="Pick a date" src="/images/calendar-clipboard.jpg"></p>
</div><ol class=simple-footnotes><li id=sf-date-the-missing-type-1>Here by <strong>datetime</strong>, we mean an object that contains
<strong>both</strong> date (year, month, day), time information (hour, minute, second,
millisecond / microsecond / nanosecond), and often a relevant timezone as well.
For example this is provided by the <code>datetime.datetime</code> <a href="https://docs.python.org/3/library/datetime.html">type</a> in Python and
<code>Date</code> in JavaScript. <a href=#sf-date-the-missing-type-1-back class=simple-footnote-back>↩</a></li><li id=sf-date-the-missing-type-2>Those
discussions usually included a phrase like "I wish the Go standard library had a
separate <code>Date</code> type"! <a href=#sf-date-the-missing-type-2-back class=simple-footnote-back>↩</a></li><li id=sf-date-the-missing-type-3>Why does the "today"
depend on the timezone? If a friend from Los Angeles calls at 11pm, but you're
in New York, today is tomorrow! (Or yesterday, depending on who says it.) <a href=#sf-date-the-missing-type-3-back class=simple-footnote-back>↩</a></li></ol>Moser's Circle Problem and Polynomial Root Asymptotes2023-07-18T00:00:00-07:002023-07-18T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2023-07-18:/2023/07/moser-circle-estimates.html<div style="text-align: center;">
<p><img alt="3b1b Moser's Circle Problem" src="/images/3b1b-moser-thumbnail.jpg"></p>
</div>
<p>Below, we'll show two facts which help understand the positive integer solutions
to the following diophantine equation:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mn>1</mn><mo>+</mo><mrow><mo fence=true>(</mo><mfrac linethickness=0px><mi>n</mi><mn>2</mn></mfrac><mo fence=true>)</mo></mrow><mo>+</mo><mrow><mo fence=true>(</mo><mfrac linethickness=0px><mi>n</mi><mn>4</mn></mfrac><mo fence=true>)</mo></mrow><mo>=</mo><msup><mn>2</mn><mi>m</mi></msup><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">1 + \binom{n}{2} + \binom{n}{4} = 2^m.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=mord><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=mord><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.7143919999999999em;vertical-align:0em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7143919999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>We'll show that there is a lone positive root and …</p><div style="text-align: center;">
<p><img alt="3b1b Moser's Circle Problem" src="/images/3b1b-moser-thumbnail.jpg"></p>
</div>
<p>Below, we'll show two facts which help understand the positive integer solutions
to the following diophantine equation:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mn>1</mn><mo>+</mo><mrow><mo fence=true>(</mo><mfrac linethickness=0px><mi>n</mi><mn>2</mn></mfrac><mo fence=true>)</mo></mrow><mo>+</mo><mrow><mo fence=true>(</mo><mfrac linethickness=0px><mi>n</mi><mn>4</mn></mfrac><mo fence=true>)</mo></mrow><mo>=</mo><msup><mn>2</mn><mi>m</mi></msup><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">1 + \binom{n}{2} + \binom{n}{4} = 2^m.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=mord><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=mord><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.7143919999999999em;vertical-align:0em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7143919999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>We'll show that there is a lone positive root and as
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>⟶</mo><mi mathvariant=normal>∞</mi></mrow><annotation encoding="application/x-tex">m \longrightarrow \infty</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.522em;vertical-align:-0.011em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟶</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class=mord>∞</span></span></span></span> the root approaches:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mroot><mrow><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><mn>4</mn></mroot><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac><mo>+</mo><mi mathvariant=script>O</mi><mrow><mo fence=true>(</mo><mfrac><mn>1</mn><mroot><mrow><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><mn>4</mn></mroot></mfrac><mo fence=true>)</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">\sqrt[4]{24 \cdot 2^m} + \frac{3}{2} + \mathcal{O}\left(\frac{1}{\sqrt[4]{24 \cdot 2^m}}\right).</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.04em;vertical-align:-0.08390500000000001em;></span><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.845534em;><span style=top:-3.023314em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.590392em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class="mord mathcal" style=margin-right:0.02778em;>O</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.2027799999999997em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7868839999999999em;><span style=top:-2.964664em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.90722em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.590392em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span><span style=top:-2.86722em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.13278em;><span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.93em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>Additionally, if this root is an integer (i.e. the relevant solutions to a
diophantine equation), then for <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>≥</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">m \geq 4</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.7719400000000001em;vertical-align:-0.13597em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≥</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>4</span></span></span></span> it must be exactly
equal to:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>n</mi><mo>=</mo><mrow><mo fence=true>⌊</mo><mroot><mrow><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><mn>4</mn></mroot><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac><mo fence=true>⌋</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">n = \left\lfloor \sqrt[4]{24 \cdot 2^m} + \frac{3}{2} \right\rfloor.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">⌊</span></span><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.845534em;><span style=top:-3.023314em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.590392em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">⌋</span></span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<h3>Contents</h3>
<ul>
<li><a href=#motivation>Motivation</a></li>
<li><a href=#open-question>Open Question</a></li>
<li><a href=#reframing>Reframing</a></li>
<li><a href=#finding-coefficients>Finding Coefficients</a></li>
<li><a href=#root-as-floor>Root as Floor</a></li>
<li><a href=#tigher-bounds>Tighter Bounds</a></li>
<li><a href=#future-work>Future Work</a></li>
</ul>
<h3 id=motivation>Motivation</h3>
<p>I started down this path after watching a <a href="https://www.youtube.com/watch?v=YtkIWDE36qU">video</a> from 3Blue1Brown<sup id=sf-moser-circle-estimates-1-back><a href=#sf-moser-circle-estimates-1 class=simple-footnote title="Grant Sanderson, aka 3Blue1Brown is awesome and I highly recommend all of his videos.">1</a></sup> where he discusses <a href="https://en.wikipedia.org/wiki/Dividing_a_circle_into_areas">Moser's circle problem</a>. In particular, he
demonstrates the formula</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msub><mi>F</mi><mi>n</mi></msub><mo>=</mo><mn>1</mn><mo>+</mo><mrow><mo fence=true>(</mo><mfrac linethickness=0px><mi>n</mi><mn>2</mn></mfrac><mo fence=true>)</mo></mrow><mo>+</mo><mrow><mo fence=true>(</mo><mfrac linethickness=0px><mi>n</mi><mn>4</mn></mfrac><mo fence=true>)</mo></mrow></mrow><annotation encoding="application/x-tex">F_n = 1 + \binom{n}{2} + \binom{n}{4}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.83333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.151392em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=mord><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=mord><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span></span></span></span></span>
</blockquote></div>
<p>for the number of distinct regions a circle is divided into when connecting
all pairs of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span></span></span></span> points around the circle in
<strong>general position</strong>.</p>
<p>The video is about showing the perils of assuming a pattern repeats
indefinitely:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msub><mi>F</mi><mn>1</mn></msub><mo>=</mo><mn>1</mn><mo separator=true>,</mo><msub><mi>F</mi><mn>2</mn></msub><mo>=</mo><mn>2</mn><mo separator=true>,</mo><msub><mi>F</mi><mn>3</mn></msub><mo>=</mo><mn>4</mn><mo separator=true>,</mo><msub><mi>F</mi><mn>4</mn></msub><mo>=</mo><mn>8</mn><mo separator=true>,</mo><msub><mi>F</mi><mn>5</mn></msub><mo>=</mo><mn>16</mn><mo separator=true>,</mo><msub><mi>F</mi><mn>6</mn></msub><mo>=</mo><mn>31</mn><mo mathvariant=normal>≠</mo><mn>32.</mn></mrow><annotation encoding="application/x-tex">F_1 = 1, F_2 = 2, F_3 = 4, F_4 = 8, F_5 = 16, F_6 = 31 \neq 32.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.83333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8777699999999999em;vertical-align:-0.19444em;></span><span class=mord>1</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8777699999999999em;vertical-align:-0.19444em;></span><span class=mord>2</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8777699999999999em;vertical-align:-0.19444em;></span><span class=mord>4</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8777699999999999em;vertical-align:-0.19444em;></span><span class=mord>8</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8777699999999999em;vertical-align:-0.19444em;></span><span class=mord>16</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=mord>31</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><span class=mrel><span class="mord vbox"><span class=thinbox><span class=rlap><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=inner><span class=mord><span class=mrel></span></span></span><span class=fix></span></span></span></span></span><span class=mrel>=</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>32.</span></span></span></span></span>
</blockquote></div>
<p>but also shows one more value equal to a power of two:
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mn>10</mn></msub><mo>=</mo><mn>256</mn></mrow><annotation encoding="application/x-tex">F_{10} = 256</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.83333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">10</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>256</span></span></span></span>.</p>
<h3 id=open-question>Open Question</h3>
<p>At the <a href="https://www.youtube.com/watch?v=YtkIWDE36qU&t=900s">end of the video</a> he poses a challenge question that piqued my
interest and that's what we'll be talking about here<sup id=sf-moser-circle-estimates-2-back><a href=#sf-moser-circle-estimates-2 class=simple-footnote title="I know the last time I wrote about math on this blog it was the same situation, i.e. an offhand comment on a popular YouTube video.">2</a></sup>: <strong>Will there ever be
another power of 2</strong>?</p>
<div style="text-align: center;">
<p><img alt="3b1b Challenge Question" src="/images/3b1b-moser-challenge-question.png"></p>
</div>
<p>There is a fairly clean <a href="https://math.stackexchange.com/a/3442247/31956">solution</a> to this on Math StackExchange, but
it uses extremely non-elementary methods (I am not a number theorist). It does
use a simple observation to transform the exponential part of the equation into
a low degree polynomial so that existing tools for solving diophantine equations
can be used. In particular, it uses the observation that <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mi>m</mi></msup></mrow><annotation encoding="application/x-tex">2^m</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.664392em;vertical-align:0em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.664392em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span></span>
is either equal to <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>k</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">k^2</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8141079999999999em;vertical-align:0em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.03148em;>k</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span> or <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><msup><mi>k</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">2k^2</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8141079999999999em;vertical-align:0em;></span><span class=mord>2</span><span class=mord><span class="mord mathnormal" style=margin-right:0.03148em;>k</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>
depending on the parity of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">m</span></span></span></span>.</p>
<p>I tried (and failed) to make progress on this challenge question by
investigating properties of a solution <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span></span></span></span> as
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">m</span></span></span></span> varies. (As opposed to what I view the more common approach
of investigating factors of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">F_n</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.83333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.151392em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span></span> as <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span></span></span></span>
varies.) However along the way I discovered some interesting facts about the
roots as <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>⟶</mo><mi mathvariant=normal>∞</mi></mrow><annotation encoding="application/x-tex">m \longrightarrow \infty</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.522em;vertical-align:-0.011em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟶</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class=mord>∞</span></span></span></span>.</p>
<h3 id=reframing>Reframing</h3>
<p>We'll reframe <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mi>n</mi></msub><mo>=</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><annotation encoding="application/x-tex">F_n = 2^m</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.83333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.151392em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.664392em;vertical-align:0em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.664392em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span></span> via a change of variables to get an
explicit Laurent series to more easily understand the behavior of the positive
root. Note that we can say <strong>the</strong> positive root: there is exactly one. To see
why, consider</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mi>f</mi><mo stretchy=false>(</mo><mi>n</mi><mo separator=true>;</mo><mi>m</mi><mo stretchy=false>)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mn>24</mn><mrow><mo fence=true>(</mo><msub><mi>F</mi><mi>n</mi></msub><mo>−</mo><msup><mn>2</mn><mi>m</mi></msup><mo fence=true>)</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><msup><mi>n</mi><mn>4</mn></msup><mo>−</mo><mn>6</mn><msup><mi>n</mi><mn>3</mn></msup><mo>+</mo><mn>23</mn><msup><mi>n</mi><mn>2</mn></msup><mo>−</mo><mn>18</mn><mi>n</mi><mo>−</mo><mn>24</mn><mrow><mo fence=true>(</mo><msup><mn>2</mn><mi>m</mi></msup><mo>−</mo><mn>1</mn><mo fence=true>)</mo></mrow><mi mathvariant=normal>.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} f(n; m) &= 24 \left(F_n - 2^m\right) \\ &= n^4 - 6n^3 + 23n^2 - 18n - 24 \left(2^m - 1\right). \end{aligned}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:3.024108em;vertical-align:-1.262054em;></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.762054em;><span style=top:-3.922054em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.10764em;>f</span><span class=mopen>(</span><span class="mord mathnormal">n</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">m</span><span class=mclose>)</span></span></span><span style=top:-2.397946em;><span class=pstrut style=height:3em;></span><span class=mord></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.262054em;><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.762054em;><span style=top:-3.922054em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>24</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.151392em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7143919999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;>)</span></span></span></span><span style=top:-2.397946em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>6</span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>23</span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>18</span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>24</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7143919999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.262054em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>This function is concave up since monic and</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msup><mi>f</mi><mrow><mo mathvariant=normal>′</mo><mo mathvariant=normal>′</mo></mrow></msup><mo stretchy=false>(</mo><mi>n</mi><mo separator=true>;</mo><mi>m</mi><mo stretchy=false>)</mo><mo>=</mo><mn>12</mn><msup><mi>n</mi><mn>2</mn></msup><mo>−</mo><mn>36</mn><mi>n</mi><mo>+</mo><mn>46</mn><mo>=</mo><mn>3</mn><msup><mrow><mo fence=true>(</mo><mn>2</mn><mi>n</mi><mo>−</mo><mn>3</mn><mo fence=true>)</mo></mrow><mn>2</mn></msup><mo>+</mo><mn>19.</mn></mrow><annotation encoding="application/x-tex">f''(n; m) = 12 n^2 - 36 n + 46 = 3\left(2n - 3\right)^2 + 19.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.051892em;vertical-align:-0.25em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.10764em;>f</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.801892em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′′</span></span></span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">n</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">m</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord>12</span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>36</span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>46</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.204008em;vertical-align:-0.25em;></span><span class=mord>3</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord>2</span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>3</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.954008em;><span style=top:-3.2029em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>19.</span></span></span></span></span>
</blockquote></div>
<p>For <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>≥</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">m \geq 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.7719400000000001em;vertical-align:-0.13597em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≥</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span> we have
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy=false>(</mo><mn>0</mn><mo separator=true>;</mo><mi>m</mi><mo stretchy=false>)</mo><mo>=</mo><mi>f</mi><mo stretchy=false>(</mo><mn>1</mn><mo separator=true>;</mo><mi>m</mi><mo stretchy=false>)</mo><mo>=</mo><mo>−</mo><mn>24</mn><mrow><mo fence=true>(</mo><msup><mn>2</mn><mi>m</mi></msup><mo>−</mo><mn>1</mn><mo fence=true>)</mo></mrow><mo><</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">f(0; m) = f(1; m) = -24\left(2^m - 1\right) < 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.10764em;>f</span><span class=mopen>(</span><span class=mord>0</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">m</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.10764em;>f</span><span class=mopen>(</span><span class=mord>1</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">m</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mord>−</span><span class=mord>24</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.664392em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span> which
guarantees a root greater than 1 and a root less than 0.</p>
<p>We'd like to understand the asymptotic root behavior, but as
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>⟶</mo><mi mathvariant=normal>∞</mi></mrow><annotation encoding="application/x-tex">m \longrightarrow \infty</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.522em;vertical-align:-0.011em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟶</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class=mord>∞</span></span></span></span> both the "input"
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mi>m</mi></msup></mrow><annotation encoding="application/x-tex">2^m</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.664392em;vertical-align:0em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.664392em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span></span> goes to infinity and the "output" <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span></span></span></span>
goes to infinity since the largest term of the polynomial will dominate:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msup><mi>n</mi><mn>4</mn></msup><mo>+</mo><mi mathvariant=script>O</mi><mrow><mo fence=true>(</mo><msup><mi>n</mi><mn>3</mn></msup><mo fence=true>)</mo></mrow><mo>=</mo><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup><mo>⟹</mo><mi>n</mi><mo>≈</mo><mroot><mrow><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><mn>4</mn></mroot><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">n^4 + \mathcal{O}\left(n^3\right) = 24 \cdot 2^m \Longrightarrow n \approx \sqrt[4]{24 \cdot 2^m}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.2141179999999998em;vertical-align:-0.35001em;></span><span class="mord mathcal" style=margin-right:0.02778em;>O</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">(</span></span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">)</span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.7383919999999999em;vertical-align:-0.024em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7143919999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟹</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.48312em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≈</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.04em;vertical-align:-0.08390500000000001em;></span><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.845534em;><span style=top:-3.023314em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.590392em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>We'd like a Taylor series at infinity that converges to infinity. However, no
such expansion exists, so we instead use a quantity that goes to infinity as
some input <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span></span> goes to zero:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msup><mi>n</mi><mn>4</mn></msup><mo>−</mo><mn>6</mn><msup><mi>n</mi><mn>3</mn></msup><mo>+</mo><mn>23</mn><msup><mi>n</mi><mn>2</mn></msup><mo>−</mo><mn>18</mn><mi>n</mi><mo>+</mo><mn>24</mn><mo>=</mo><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup><mo>=</mo><mfrac><mn>1</mn><msup><mi>X</mi><mn>4</mn></msup></mfrac><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">n^4 - 6n^3 + 23n^2 - 18n + 24 = 24 \cdot 2^m = \frac{1}{X^4}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord>6</span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord>23</span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>18</span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>24</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.7143919999999999em;vertical-align:0em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7143919999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.740108em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>This satisfies <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><msup><mi>X</mi><mn>4</mn></msup></mfrac><mo>⟶</mo><mi mathvariant=normal>∞</mi></mrow><annotation encoding="application/x-tex">\frac{1}{X^4} \longrightarrow \infty</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.190108em;vertical-align:-0.345em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.845108em;><span style=top:-2.6550000000000002em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7463142857142857em;><span style=top:-2.786em;margin-right:0.07142857142857144em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.394em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.345em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟶</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class=mord>∞</span></span></span></span> as
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo>⟶</mo><msup><mn>0</mn><mo>+</mo></msup></mrow><annotation encoding="application/x-tex">X \longrightarrow 0^+</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.69433em;vertical-align:-0.011em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟶</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.771331em;vertical-align:0em;></span><span class=mord><span class=mord>0</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.771331em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mbin mtight">+</span></span></span></span></span></span></span></span></span></span></span> but since
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>∼</mo><mroot><mfrac><mn>1</mn><msup><mi>X</mi><mn>4</mn></msup></mfrac><mn>4</mn></mroot><mo>=</mo><mfrac><mn>1</mn><mi>X</mi></mfrac></mrow><annotation encoding="application/x-tex">n \sim \sqrt[4]{\frac{1}{X^4}} = \frac{1}{X}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>∼</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.84em;vertical-align:-0.604946em;></span><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7002848em;><span style=top:-2.8780648em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.235054em;><span class=svg-align style=top:-3.8em;><span class=pstrut style=height:3.8em;></span><span class=mord style=padding-left:1em;><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.845108em;><span style=top:-2.6550000000000002em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7463142857142857em;><span style=top:-2.786em;margin-right:0.07142857142857144em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.394em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.345em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style=top:-3.195054em;><span class=pstrut style=height:3.8em;></span><span class=hide-tail style=min-width:1.02em;height:1.8800000000000001em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.8800000000000001em viewBox="0 0 400000 1944" preserveAspectRatio="xMinYMin slice"><path d="M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.604946em;><span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.190108em;vertical-align:-0.345em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.845108em;><span style=top:-2.6550000000000002em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.07847em;>X</span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.394em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.345em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> it doesn't
solve the <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>⟶</mo><mi mathvariant=normal>∞</mi></mrow><annotation encoding="application/x-tex">n \longrightarrow \infty</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.522em;vertical-align:-0.011em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟶</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class=mord>∞</span></span></span></span> problem. For that, we
use the substitution <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mo>=</mo><mi>n</mi><mi>X</mi></mrow><annotation encoding="application/x-tex">s = n X</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span></span> and now can start to pursue
a Taylor series for our root via</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msup><mrow><mo fence=true>(</mo><mi>s</mi><mi mathvariant=normal>/</mi><mi>X</mi><mo fence=true>)</mo></mrow><mn>4</mn></msup><mo>−</mo><mn>6</mn><msup><mrow><mo fence=true>(</mo><mi>s</mi><mi mathvariant=normal>/</mi><mi>X</mi><mo fence=true>)</mo></mrow><mn>3</mn></msup><mo>+</mo><mn>23</mn><msup><mrow><mo fence=true>(</mo><mi>s</mi><mi mathvariant=normal>/</mi><mi>X</mi><mo fence=true>)</mo></mrow><mn>2</mn></msup><mo>−</mo><mn>18</mn><mrow><mo fence=true>(</mo><mi>s</mi><mi mathvariant=normal>/</mi><mi>X</mi><mo fence=true>)</mo></mrow><mo>+</mo><mn>24</mn><mo>=</mo><mfrac><mn>1</mn><msup><mi>X</mi><mn>4</mn></msup></mfrac></mrow><annotation encoding="application/x-tex">\left(s / X\right)^4 - 6\left(s / X\right)^3 + 23\left(s / X\right)^2 - 18\left(s / X\right) + 24 = \frac{1}{X^4}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.204008em;vertical-align:-0.25em;></span><span class=minner><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal">s</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.954008em;><span style=top:-3.2029em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.204008em;vertical-align:-0.25em;></span><span class=mord>6</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal">s</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.954008em;><span style=top:-3.2029em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.204008em;vertical-align:-0.25em;></span><span class=mord>23</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal">s</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.954008em;><span style=top:-3.2029em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mord>18</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal">s</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>24</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.740108em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>which is equivalent to finding roots of the parameterized polynomial</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>g</mi><mo stretchy=false>(</mo><mi>s</mi><mo separator=true>;</mo><mi>X</mi><mo stretchy=false>)</mo><mo>=</mo><msup><mi>s</mi><mn>4</mn></msup><mo>−</mo><mn>6</mn><mi>X</mi><msup><mi>s</mi><mn>3</mn></msup><mo>+</mo><mn>23</mn><msup><mi>X</mi><mn>2</mn></msup><msup><mi>s</mi><mn>2</mn></msup><mo>−</mo><mn>18</mn><msup><mi>X</mi><mn>3</mn></msup><mi>s</mi><mo>+</mo><mrow><mo fence=true>(</mo><mn>24</mn><msup><mi>X</mi><mn>4</mn></msup><mo>−</mo><mn>1</mn><mo fence=true>)</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">g(s; X) = s^4 - 6X s^3 + 23 X^2 s^2 - 18 X^3 s + \left(24X^4 - 1\right).</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>g</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord>6</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord>23</span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord>18</span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.2141179999999998em;vertical-align:-0.35001em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">(</span></span><span class=mord>24</span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">)</span></span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>This polynomial allows us to <strong>define</strong> the positive root
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">\alpha(X)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span></span></span></span> as an implicit function via</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mn>0</mn><mo>≡</mo><mi>g</mi><mrow><mo fence=true>(</mo><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo><mo separator=true>;</mo><mi>X</mi><mo fence=true>)</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">0 \equiv g\left(\alpha(X); X\right).</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≡</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>g</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>We'll start from the Taylor series</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><mo>+</mo><msub><mi>a</mi><mn>1</mn></msub><mi>X</mi><mo>+</mo><mfrac><msub><mi>a</mi><mn>2</mn></msub><mn>2</mn></mfrac><msup><mi>X</mi><mn>2</mn></msup><mo>+</mo><mi mathvariant=script>O</mi><mrow><mo fence=true>(</mo><msup><mi>X</mi><mn>3</mn></msup><mo fence=true>)</mo></mrow></mrow><annotation encoding="application/x-tex">\alpha(X) = a_0 + a_1 X + \frac{a_2}{2} X^2 + \mathcal{O}\left(X^3\right)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.73333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.83333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.7935599999999998em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.2141179999999998em;vertical-align:-0.35001em;></span><span class="mord mathcal" style=margin-right:0.02778em;>O</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">(</span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">)</span></span></span></span></span></span></span>
</blockquote></div>
<p>and transform to the Laurent series for <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mi>s</mi><mi mathvariant=normal>/</mi><mi>X</mi></mrow><annotation encoding="application/x-tex">n = s / X</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal">s</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span></span></p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mfrac><msub><mi>a</mi><mn>0</mn></msub><mi>X</mi></mfrac><mo>+</mo><msub><mi>a</mi><mn>1</mn></msub><mo>+</mo><mfrac><msub><mi>a</mi><mn>2</mn></msub><mn>2</mn></mfrac><mi>X</mi><mo>+</mo><mi mathvariant=script>O</mi><mrow><mo fence=true>(</mo><msup><mi>X</mi><mn>2</mn></msup><mo fence=true>)</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">\frac{a_0}{X} + a_1 + \frac{a_2}{2} X + \mathcal{O}\left(X^2\right).</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.7935599999999998em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.73333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.7935599999999998em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1075599999999999em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.2141179999999998em;vertical-align:-0.35001em;></span><span class="mord mathcal" style=margin-right:0.02778em;>O</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">(</span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">)</span></span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<h3 id=finding-coefficients>Finding Coefficients</h3>
<p>To find the first few terms of this expansion, we'll utilize <a href="https://www.sympy.org/en/index.html">SymPy</a>.
First, we'll set up our variables, our parameterized polynomial
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>g</mi><mo stretchy=false>(</mo><mi>s</mi><mo separator=true>;</mo><mi>X</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">g(s; X)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>g</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span></span></span></span> and the first three terms of the Taylor series
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">\alpha(X)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span></span></span></span> (utilizing the <strong>very</strong> useful <code>sympy.Order</code> type
in SymPy):</p>
<div class=highlight><pre><span></span><code><span class=n>In</span> <span class=p>[</span><span class=mi>1</span><span class=p>]:</span> <span class=kn>import</span> <span class=nn>sympy</span><span class=p>;</span> <span class=n>sympy</span><span class=o>.</span><span class=n>__version__</span>
<span class=n>Out</span><span class=p>[</span><span class=mi>1</span><span class=p>]:</span> <span class=s1>'1.12'</span>
<span class=n>In</span> <span class=p>[</span><span class=mi>2</span><span class=p>]:</span> <span class=n>a0</span><span class=p>,</span> <span class=n>a1</span><span class=p>,</span> <span class=n>a2</span><span class=p>,</span> <span class=n>s</span><span class=p>,</span> <span class=n>X</span> <span class=o>=</span> <span class=n>sympy</span><span class=o>.</span><span class=n>symbols</span><span class=p>(</span><span class=s2>"a0, a1, a2, s, X"</span><span class=p>)</span>
<span class=n>In</span> <span class=p>[</span><span class=mi>3</span><span class=p>]:</span> <span class=n>g</span> <span class=o>=</span> <span class=n>s</span><span class=o>**</span><span class=mi>4</span> <span class=o>-</span> <span class=mi>6</span> <span class=o>*</span> <span class=n>X</span> <span class=o>*</span> <span class=n>s</span><span class=o>**</span><span class=mi>3</span> <span class=o>+</span> <span class=mi>23</span> <span class=o>*</span> <span class=n>X</span><span class=o>**</span><span class=mi>2</span> <span class=o>*</span> <span class=n>s</span><span class=o>**</span><span class=mi>2</span> <span class=o>-</span> <span class=mi>18</span> <span class=o>*</span> <span class=n>X</span><span class=o>**</span><span class=mi>3</span> <span class=o>*</span> <span class=n>s</span> <span class=o>+</span> <span class=p>(</span><span class=mi>24</span> <span class=o>*</span> <span class=n>X</span><span class=o>**</span><span class=mi>4</span> <span class=o>-</span> <span class=mi>1</span><span class=p>)</span>
<span class=n>In</span> <span class=p>[</span><span class=mi>4</span><span class=p>]:</span> <span class=n>alpha</span> <span class=o>=</span> <span class=n>a0</span> <span class=o>+</span> <span class=n>a1</span> <span class=o>*</span> <span class=n>X</span> <span class=o>+</span> <span class=n>a2</span> <span class=o>/</span> <span class=mi>2</span> <span class=o>*</span> <span class=n>X</span><span class=o>**</span><span class=mi>2</span> <span class=o>+</span> <span class=n>sympy</span><span class=o>.</span><span class=n>Order</span><span class=p>(</span><span class=n>X</span><span class=o>**</span><span class=mi>3</span><span class=p>)</span>
</code></pre></div>
<p>Substituting <code>alpha</code> and expanding, we have a series with quadratic terms
in <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span></span> and as expected a tail of the form
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=script>O</mi><mrow><mo fence=true>(</mo><msup><mi>X</mi><mn>3</mn></msup><mo fence=true>)</mo></mrow></mrow><annotation encoding="application/x-tex">\mathcal{O}\left(X^3\right)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.20001em;vertical-align:-0.35001em;></span><span class="mord mathcal" style=margin-right:0.02778em;>O</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">(</span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">)</span></span></span></span></span></span>:</p>
<div class=highlight><pre><span></span><code><span class=n>In</span> <span class=p>[</span><span class=mi>5</span><span class=p>]:</span> <span class=n>g</span><span class=o>.</span><span class=n>subs</span><span class=p>({</span><span class=n>s</span><span class=p>:</span> <span class=n>alpha</span><span class=p>})</span><span class=o>.</span><span class=n>expand</span><span class=p>()</span>
<span class=n>Out</span><span class=p>[</span><span class=mi>5</span><span class=p>]:</span> <span class=o>-</span><span class=mi>1</span> <span class=o>+</span> <span class=n>a0</span><span class=o>**</span><span class=mi>4</span> <span class=o>-</span> <span class=mi>6</span><span class=o>*</span><span class=n>X</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>3</span> <span class=o>+</span> <span class=mi>4</span><span class=o>*</span><span class=n>X</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>3</span><span class=o>*</span><span class=n>a1</span> <span class=o>+</span> <span class=mi>23</span><span class=o>*</span><span class=n>X</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>2</span> <span class=o>-</span> <span class=mi>18</span><span class=o>*</span><span class=n>X</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=n>a1</span> <span class=o>+</span> <span class=mi>6</span><span class=o>*</span><span class=n>X</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=n>a1</span><span class=o>**</span><span class=mi>2</span> <span class=o>+</span> <span class=mi>2</span><span class=o>*</span><span class=n>X</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>3</span><span class=o>*</span><span class=n>a2</span> <span class=o>+</span> <span class=n>O</span><span class=p>(</span><span class=n>X</span><span class=o>**</span><span class=mi>3</span><span class=p>)</span>
<span class=n>In</span> <span class=p>[</span><span class=mi>6</span><span class=p>]:</span> <span class=n>T2</span> <span class=o>=</span> <span class=n>sympy</span><span class=o>.</span><span class=n>Poly</span><span class=p>(</span><span class=n>g</span><span class=o>.</span><span class=n>subs</span><span class=p>({</span><span class=n>s</span><span class=p>:</span> <span class=n>alpha</span><span class=p>})</span><span class=o>.</span><span class=n>expand</span><span class=p>()</span><span class=o>.</span><span class=n>removeO</span><span class=p>(),</span> <span class=n>X</span><span class=p>)</span>
<span class=n>In</span> <span class=p>[</span><span class=mi>7</span><span class=p>]:</span> <span class=n>T2</span>
<span class=n>Out</span><span class=p>[</span><span class=mi>7</span><span class=p>]:</span> <span class=n>Poly</span><span class=p>((</span><span class=mi>2</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>3</span><span class=o>*</span><span class=n>a2</span> <span class=o>+</span> <span class=mi>6</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=n>a1</span><span class=o>**</span><span class=mi>2</span> <span class=o>-</span> <span class=mi>18</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=n>a1</span> <span class=o>+</span> <span class=mi>23</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>2</span><span class=p>)</span><span class=o>*</span><span class=n>X</span><span class=o>**</span><span class=mi>2</span> <span class=o>+</span> <span class=p>(</span><span class=mi>4</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>3</span><span class=o>*</span><span class=n>a1</span> <span class=o>-</span> <span class=mi>6</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>3</span><span class=p>)</span><span class=o>*</span><span class=n>X</span> <span class=o>+</span> <span class=n>a0</span><span class=o>**</span><span class=mi>4</span> <span class=o>-</span> <span class=mi>1</span><span class=p>,</span> <span class=n>X</span><span class=p>,</span> <span class=n>domain</span><span class=o>=</span><span class=s1>'ZZ[a0,a1,a2]'</span><span class=p>)</span>
</code></pre></div>
<p>Setting the coefficients of the first three terms to zero, we'll have our
expansion:</p>
<div class=highlight><pre><span></span><code><span class=n>In</span> <span class=p>[</span><span class=mi>8</span><span class=p>]:</span> <span class=n>T2</span><span class=o>.</span><span class=n>coeff_monomial</span><span class=p>(</span><span class=mi>1</span><span class=p>)</span>
<span class=n>Out</span><span class=p>[</span><span class=mi>8</span><span class=p>]:</span> <span class=n>a0</span><span class=o>**</span><span class=mi>4</span> <span class=o>-</span> <span class=mi>1</span>
<span class=n>In</span> <span class=p>[</span><span class=mi>9</span><span class=p>]:</span> <span class=n>T2</span><span class=o>.</span><span class=n>coeff_monomial</span><span class=p>(</span><span class=n>X</span><span class=p>)</span><span class=o>.</span><span class=n>factor</span><span class=p>()</span>
<span class=n>Out</span><span class=p>[</span><span class=mi>9</span><span class=p>]:</span> <span class=mi>2</span><span class=o>*</span><span class=n>a0</span><span class=o>**</span><span class=mi>3</span><span class=o>*</span><span class=p>(</span><span class=mi>2</span><span class=o>*</span><span class=n>a1</span> <span class=o>-</span> <span class=mi>3</span><span class=p>)</span>
<span class=n>In</span> <span class=p>[</span><span class=mi>10</span><span class=p>]:</span> <span class=n>T2</span><span class=o>.</span><span class=n>coeff_monomial</span><span class=p>(</span><span class=n>X</span><span class=o>**</span><span class=mi>2</span><span class=p>)</span><span class=o>.</span><span class=n>factor</span><span class=p>()</span>
<span class=n>Out</span><span class=p>[</span><span class=mi>10</span><span class=p>]:</span> <span class=n>a0</span><span class=o>**</span><span class=mi>2</span><span class=o>*</span><span class=p>(</span><span class=mi>2</span><span class=o>*</span><span class=n>a0</span><span class=o>*</span><span class=n>a2</span> <span class=o>+</span> <span class=mi>6</span><span class=o>*</span><span class=n>a1</span><span class=o>**</span><span class=mi>2</span> <span class=o>-</span> <span class=mi>18</span><span class=o>*</span><span class=n>a1</span> <span class=o>+</span> <span class=mi>23</span><span class=p>)</span>
</code></pre></div>
<p>Since we want the <strong>positive</strong> root, we choose
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo stretchy=false>(</mo><mn>0</mn><mo stretchy=false>)</mo><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\alpha(0) = a_0 = 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class=mord>0</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.58056em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span>. Independent of this value we also
see <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mn>1</mn></msub><mo>=</mo><mfrac><mn>3</mn><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">a_1 = \frac{3}{2}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.58056em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.190108em;vertical-align:-0.345em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.845108em;><span style=top:-2.6550000000000002em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.394em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.345em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> (since all four possible values of
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">a_0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.58056em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span></span> are nonzero). Finally solving for the last term:</p>
<div class=highlight><pre><span></span><code><span class=n>In</span> <span class=p>[</span><span class=mi>11</span><span class=p>]:</span> <span class=n>T2</span><span class=o>.</span><span class=n>coeff_monomial</span><span class=p>(</span><span class=n>X</span><span class=o>**</span><span class=mi>2</span><span class=p>)</span><span class=o>.</span><span class=n>subs</span><span class=p>({</span><span class=n>a0</span><span class=p>:</span> <span class=mi>1</span><span class=p>,</span> <span class=n>a1</span><span class=p>:</span> <span class=n>sympy</span><span class=o>.</span><span class=n>Rational</span><span class=p>(</span><span class=mi>3</span><span class=p>,</span> <span class=mi>2</span><span class=p>)})</span><span class=o>.</span><span class=n>factor</span><span class=p>()</span>
<span class=n>Out</span><span class=p>[</span><span class=mi>11</span><span class=p>]:</span> <span class=p>(</span><span class=mi>4</span><span class=o>*</span><span class=n>a2</span> <span class=o>+</span> <span class=mi>19</span><span class=p>)</span><span class=o>/</span><span class=mi>2</span>
</code></pre></div>
<p>Putting it all together:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo><mo>=</mo><mn>1</mn><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac><mi>X</mi><mo>−</mo><mfrac><mn>19</mn><mn>8</mn></mfrac><msup><mi>X</mi><mn>2</mn></msup><mo>+</mo><mi mathvariant=script>O</mi><mrow><mo fence=true>(</mo><msup><mi>X</mi><mn>3</mn></msup><mo fence=true>)</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">\alpha(X) = 1 + \frac{3}{2} X - \frac{19}{8} X^2 + \mathcal{O}\left(X^3\right).</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>8</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>19</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.2141179999999998em;vertical-align:-0.35001em;></span><span class="mord mathcal" style=margin-right:0.02778em;>O</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">(</span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">)</span></span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<h3 id=root-as-floor>Root as Floor</h3>
<p>We'll show below that
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>X</mi><mo><</mo><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo><mo><</mo><mn>1</mn><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac><mi>X</mi></mrow><annotation encoding="application/x-tex">1 + \frac{1}{2} X < \alpha(X) < 1 + \frac{3}{2} X</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.190108em;vertical-align:-0.345em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.845108em;><span style=top:-2.6550000000000002em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.394em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.345em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.190108em;vertical-align:-0.345em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.845108em;><span style=top:-2.6550000000000002em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.394em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.345em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span></span> for
small enough <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span></span><sup id=sf-moser-circle-estimates-3-back><a href=#sf-moser-circle-estimates-3 class=simple-footnote title="Note that the negative quadratic term in the Taylor series for the root indicates the upper bound.">3</a></sup>. Once established, this means</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mfrac><mn>1</mn><mi>X</mi></mfrac><mo>+</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mo><</mo><mi>n</mi><mo>=</mo><mfrac><mrow><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo></mrow><mi>X</mi></mfrac><mo><</mo><mfrac><mn>1</mn><mi>X</mi></mfrac><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{1}{X} + \frac{1}{2} < n = \frac{\alpha(X)}{X} < \frac{1}{X} + \frac{3}{2}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.113em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.427em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>and since this interval has a width of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span> we have
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mrow><mo fence=true>⌊</mo><mfrac><mn>1</mn><mi>X</mi></mfrac><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac><mo fence=true>⌋</mo></mrow></mrow><annotation encoding="application/x-tex">n = \left\lfloor \frac{1}{X} + \frac{3}{2} \right\rfloor</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.20001em;vertical-align:-0.35001em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">⌊</span></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.845108em;><span style=top:-2.6550000000000002em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.07847em;>X</span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.394em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.345em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.845108em;><span style=top:-2.6550000000000002em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.394em;><span class=pstrut style=height:3em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.345em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">⌋</span></span></span></span></span></span>.
The connection to <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">m</span></span></span></span> comes in via:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mfrac><mn>1</mn><msup><mi>X</mi><mn>4</mn></msup></mfrac><mo>=</mo><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup><mo>⟺</mo><mfrac><mn>1</mn><mi>X</mi></mfrac><mo>=</mo><mroot><mrow><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><mn>4</mn></mroot><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">\frac{1}{X^4} = 24 \cdot 2^m \Longleftrightarrow \frac{1}{X} = \sqrt[4]{24 \cdot 2^m}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.740108em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.7383919999999999em;vertical-align:-0.024em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7143919999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟺</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.04em;vertical-align:-0.08390500000000001em;></span><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.845534em;><span style=top:-3.023314em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.590392em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>We can establish the upper bound via:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>g</mi><mrow><mo fence=true>(</mo><mn>1</mn><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac><mi>X</mi><mo separator=true>;</mo><mi>X</mi><mo fence=true>)</mo></mrow><mo>=</mo><mfrac><mn>537</mn><mn>16</mn></mfrac><msup><mi>X</mi><mn>4</mn></msup><mo>+</mo><mn>24</mn><msup><mi>X</mi><mn>3</mn></msup><mo>+</mo><mfrac><mn>19</mn><mn>2</mn></mfrac><msup><mi>X</mi><mn>2</mn></msup><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">g\left(1 + \frac{3}{2} X; X\right) = \frac{537}{16} X^4 + 24 X^3 + \frac{19}{2} X^2.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>g</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>16</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>537</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord>24</span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>19</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>This quantity is always positive for <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span></span></span></span> in our domain, which
means it is to the right of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">\alpha(X)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span></span></span></span> due to the concavity
of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>g</mi></mrow><annotation encoding="application/x-tex">g</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>g</span></span></span></span>.</p>
<div style="text-align: center;">
<p><img alt="3b1b Challenge Question" src="/images/moser-upper-bound.png"></p>
</div>
<p>For the lower bound:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>g</mi><mrow><mo fence=true>(</mo><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>X</mi><mo separator=true>;</mo><mi>X</mi><mo fence=true>)</mo></mrow><mo>=</mo><mfrac><mn>321</mn><mn>16</mn></mfrac><msup><mi>X</mi><mn>4</mn></msup><mo>+</mo><msup><mi>X</mi><mn>3</mn></msup><mo>+</mo><mfrac><mn>31</mn><mn>2</mn></mfrac><msup><mi>X</mi><mn>2</mn></msup><mo>−</mo><mn>4</mn><mi>X</mi><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">g\left(1 + \frac{1}{2} X; X\right) = \frac{321}{16} X^4 + X^3 + \frac{31}{2} X^2 - 4X.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>g</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mpunct>;</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>16</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>321</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>31</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class=mord>4</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>This quantity is negative for <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo><</mo><mn>0.2371</mn></mrow><annotation encoding="application/x-tex">X < 0.2371</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.72243em;vertical-align:-0.0391em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0.2371</span></span></span></span> which
first happens when <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">m = 4</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>4</span></span></span></span> and remains negative
thereafter:</p>
<div style="text-align: center;">
<p><img alt="3b1b Challenge Question" src="/images/moser-lower-bound-01.png"></p>
</div>
<h3 id=tigher-bounds>Tighter Bounds</h3>
<p>In an attempt to show that there could be no more solutions to the
original diophantine equation, I tightened the bounds on
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo stretchy=false>(</mo><mi>X</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">\alpha(X)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.0037em;>α</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mclose>)</span></span></span></span> and explored the behavior. In fact, for
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>≥</mo><mn>20</mn></mrow><annotation encoding="application/x-tex">m \geq 20</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.7719400000000001em;vertical-align:-0.13597em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≥</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>20</span></span></span></span> we have</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mroot><mrow><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><mn>4</mn></mroot><mo>+</mo><mn>1.46</mn><mo><</mo><mi>n</mi><mo><</mo><mroot><mrow><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><mn>4</mn></mroot><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">\sqrt[4]{24 \cdot 2^m} + 1.46 < n < \sqrt[4]{24 \cdot 2^m} + \frac{3}{2}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.04em;vertical-align:-0.08390500000000001em;></span><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.845534em;><span style=top:-3.023314em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.590392em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.68354em;vertical-align:-0.0391em;></span><span class=mord>1.46</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.5782em;vertical-align:-0.0391em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.04em;vertical-align:-0.08390500000000001em;></span><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.845534em;><span style=top:-3.023314em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.590392em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>which is a very small window of width <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0.04</mn></mrow><annotation encoding="application/x-tex">0.04</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0.04</span></span></span></span>. I was hoping to
show that for large enough <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">m</span></span></span></span> this window contains no
integers,= but unfortunately it appears that the window contains an integer
about 4% of the time. Plotting the number of such windows
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>C</mi><mn>1.46</mn></msub><mo stretchy=false>(</mo><mi>m</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">C_{1.46}(m)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.07153em;>C</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.07153em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1.46</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">m</span><span class=mclose>)</span></span></span></span> against a line with slope
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0.04</mn></mrow><annotation encoding="application/x-tex">0.04</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0.04</span></span></span></span>:</p>
<!--
C_{1.46}(m) = \\left| \\left\\{z \\in \\mathbb{Z} \\mid 1.46 < z - \\sqrt[4]{24 \\cdot 2^{\\ell}} < 1.5 \\text{ for } \\ell \\leq m \\right\} \\right|
-->
<div style="text-align: center;">
<p><img alt="3b1b Challenge Question" src="/images/moser-integers-in-window.png"></p>
</div>
<h3 id=future-work>Future Work</h3>
<p>Though I didn't get the result I was hoping for, I did have a lot of fun
exploring the behavior of roots as
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>⟶</mo><mi mathvariant=normal>∞</mi></mrow><annotation encoding="application/x-tex">m \longrightarrow \infty</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.522em;vertical-align:-0.011em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟶</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class=mord>∞</span></span></span></span>. I do think there is more
progress to be made in this direction. For example, in order for our expected
root to <strong>actually</strong> be a root, we must have</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mn>24</mn><mrow><mo fence=true>(</mo><msup><mn>2</mn><mi>m</mi></msup><mo>−</mo><mn>1</mn><mo fence=true>)</mo></mrow><mo>≡</mo><mn>0</mn><mtext> </mtext><mo lspace=0.22em rspace=0.22em><mrow><mi mathvariant=normal>m</mi><mi mathvariant=normal>o</mi><mi mathvariant=normal>d</mi></mrow></mo><mtext> </mtext><mrow><mo fence=true>⌊</mo><mroot><mrow><mn>24</mn><mo>⋅</mo><msup><mn>2</mn><mi>m</mi></msup></mrow><mn>4</mn></mroot><mo>+</mo><mfrac><mn>3</mn><mn>2</mn></mfrac><mo fence=true>⌋</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">24 \left(2^m - 1\right) \equiv 0 \bmod{\left\lfloor \sqrt[4]{24 \cdot 2^m} + \frac{3}{2} \right\rfloor}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mord>24</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7143919999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≡</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.69444em;vertical-align:0em;></span><span class=mord>0</span><span class=mspace style=margin-right:0.05555555555555555em;></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin><span class=mord><span class="mord mathrm">mod</span></span></span><span class=mspace style=margin-right:0.05555555555555555em;></span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=mord><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">⌊</span></span><span class="mord sqrt"><span class=root><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.845534em;><span style=top:-3.023314em;><span class=pstrut style=height:2.5em;></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>24</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.590392em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">⌋</span></span></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>but it appears that <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>=</mo><mn>36</mn></mrow><annotation encoding="application/x-tex">m = 36</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">m</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>36</span></span></span></span> is the last time this is
satisfied.</p><ol class=simple-footnotes><li id=sf-moser-circle-estimates-1>Grant
Sanderson, aka <a href="https://www.youtube.com/@3blue1brown">3Blue1Brown</a> is awesome and I highly recommend all of his
videos. <a href=#sf-moser-circle-estimates-1-back class=simple-footnote-back>↩</a></li><li id=sf-moser-circle-estimates-2>I know the
<a href="/2021/10/elementary-elliptic">last time</a> I wrote about math on this blog it was the same situation, i.e.
an offhand comment on a popular YouTube video. <a href=#sf-moser-circle-estimates-2-back class=simple-footnote-back>↩</a></li><li id=sf-moser-circle-estimates-3>Note that the negative
quadratic term in the Taylor series for the root indicates the
upper bound. <a href=#sf-moser-circle-estimates-3-back class=simple-footnote-back>↩</a></li></ol>Managing Tailscale subnet routers with Terraform2022-08-04T00:00:00-07:002022-08-04T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2022-08-04:/2022/08/tailscale-terraform-fargate.html<div style="text-align: center;">
<p><img alt="Tailscale, Terraform, and Fargate" src="/images/tailscale-terraform-fargate.png"></p>
</div>
<blockquote>
<p>This is cross-posted from the Hardfin engineering <a href="https://engineering.hardfin.com/2022/08/tailscale-terraform-fargate/">blog</a>.</p>
</blockquote>
<p>As a small and growing team, we need to focus our operational efforts as much as
possible. Using <a href="https://tailscale.com/">Tailscale</a> as our VPN is very much aligned with this need.
It's simple, with no central control plane to manage or other significant
operational …</p><div style="text-align: center;">
<p><img alt="Tailscale, Terraform, and Fargate" src="/images/tailscale-terraform-fargate.png"></p>
</div>
<blockquote>
<p>This is cross-posted from the Hardfin engineering <a href="https://engineering.hardfin.com/2022/08/tailscale-terraform-fargate/">blog</a>.</p>
</blockquote>
<p>As a small and growing team, we need to focus our operational efforts as much as
possible. Using <a href="https://tailscale.com/">Tailscale</a> as our VPN is very much aligned with this need.
It's simple, with no central control plane to manage or other significant
operational burden for our team.</p>
<p>In addition to providing a secure internal network for peer-to-peer
communications, Tailscale enables us to securely access databases and services
deployed in our AWS accounts via <a href="https://tailscale.com/kb/1019/subnets/">subnet routers</a>.</p>
<p>We run one subnet router per AWS VPC as an ECS <a href="https://aws.amazon.com/fargate/">Fargate</a> task and manage
the deployment with Terraform. Today we are releasing the
<code>hardfinhq/tailscale-subnet-router</code> Terraform <a href="https://registry.terraform.io/modules/hardfinhq/tailscale-subnet-router">module</a> to share our tools
for managing subnet routers.</p>
<h2>Why Tailscale?</h2>
<p>Nearly every day I see a new Tailscale user tweeting that they can't believe how
quick and easy it is to set up. One of the biggest hallmarks of Tailscale is
one we hope to emulate at Hardfin: it <strong>just works</strong>.</p>
<p>Our primary use case for a VPN is secure access to deployed environments.
However, Tailscale also enables a new kind of lightweight collaboration for
distributed teams. The peer-to-peer nature of a mesh VPN allows our team to
share workspaces and run low fidelity internal services with almost no effort:</p>
<ul>
<li>Working on a branch and want to share <code>localhost:3000</code> with the team? Just
bind your webserver to <code>0.0.0.0</code><sup id=sf-tailscale-terraform-fargate-1-back><a href=#sf-tailscale-terraform-fargate-1 class=simple-footnote title="Or your 100.x.y.z Tailscale IP if you'd like to be more surgical when binding to network interfaces.">1</a></sup> and
share a link using your machine's magic DNS name, e.g.
<code>fuzzy.hardfinhq.org.github.beta.tailscale.net</code>.</li>
<li>Need a place to serve developer docs (<code>godoc -http=:6060</code>) without the cost or
complexity of the cloud? Park a bare metal server in a closet and connect it
to your Tailnet.</li>
<li>Want static code coverage reports in <code>main</code> for the team to keep an eye on
quality over time? SSH into that bare metal server and add another static
site.</li>
</ul>
<p>Not only do we love the feature set, we also have a mountain of respect for the
Tailscale team. Tailscale is filled with internet OGs that have experience
running large networks, infrastructure at hyperscalers, and developing and
deploying <a href="https://www.wireguard.com/">WireGuard</a>. This experience manifests in the product: Tailscale
continues to work in <a href="https://tailscale.com/blog/how-nat-traversal-works/">thorny</a> networking conditions when most other VPNs
are not able to. Their ability to clearly communicate
<a href="https://tailscale.com/blog/how-tailscale-works/">deep technical ideas</a> is also one we hope to emulate right here in our
engineering blog.</p>
<h2>Why Fargate?</h2>
<p>Running the services used by our customers is our core operational charter. The
overhead of anything else must be carefully weighed and usually our answer is to
live without tools that have <strong>any</strong> operational overhead.</p>
<p>For example, our founding team has deep experience with HashiCorp Vault, but we
decided not to use it because <strong>someone</strong> would need to hold the pager. Instead
we use <a href="https://aws.amazon.com/secrets-manager/">AWS Secrets Manager</a> for secrets and <a href="https://aws.amazon.com/kms/">AWS KMS</a> for transit
encryption. Though the HashiCorp Vault feature set is more robust, the added
benefit isn't worth the cost of running Vault with a small team.</p>
<p>ECS Fargate really fits our philosophy and delivers on the promise of the cloud.
It is serverless in the sense that we care about: we don't have a
cluster<sup id=sf-tailscale-terraform-fargate-2-back><a href=#sf-tailscale-terraform-fargate-2 class=simple-footnote title="Our founding team has deep experience with Kubernetes as well but chose not to use it because of the operational burden. An ECS task definition is very similar to a Kubernetes pod spec already, so we get many of the same benefits afforded by Kubernetes.">2</a></sup> or compute nodes (i.e. servers) to
administer. Fargate provides a great blend of flexibility and focus. Though
<a href="https://firecracker-microvm.github.io/">Firecracker</a> is used to enable serverless at AWS in both Fargate and
Lambda, we prefer the flexibility of Docker containers and the control afforded
by long-lived processes over the FaaS model.</p>
<h2>Using the module</h2>
<p>As we've mentioned <a href="/2022/04/emulate-rds-permissions">previously</a>, we are big proponents of
Infrastructure-as-Code at Hardfin. With the <code>hardfinhq/tailscale-subnet-router</code>
<a href="https://registry.terraform.io/modules/hardfinhq/tailscale-subnet-router">module</a>, we are able to define all of the resources needed for a subnet
router declaratively. We can easily add a subnet router every time we bring up a
new VPC. For example:</p>
<div class=highlight><pre><span></span><code><span class=k>module</span> <span class=s>"sandbox"</span> {
<span class=nb>source</span> = <span class=s>"hardfinhq/tailscale-subnet-router/aws"</span>
<span class=nb>version</span> = <span class=s>"1.20220802.1"</span>
<span class=n>vpc</span> = <span class=s>"sandbox"</span>
<span class=n>subnet_group</span> = <span class=s>"sandbox-igw-zz-minotaur-7"</span>
<span class=n>security_group_ids</span> = [<span class=n>data</span>.<span class=n>aws_security_group</span>.<span class=n>vpn</span>.<span class=nb>id</span>]
<span class=n>target_ecs_cluster</span> = <span class=s>"sandbox-spot"</span>
<span class=n>tailscale_auth_key_secret</span> = <span class=s>"sandbox-tailscale-auth-key"</span>
<span class=n>tailscale_docker_repository</span> = <span class=s>"tailscale"</span>
<span class=n>tailscale_docker_tag</span> = <span class=s>"sha-a0063fef6ccfa4dc689642d60637a124c60b1be3"</span>
}
<span class=n>data</span> <span class=s>"aws_security_group"</span> <span class=s>"vpn"</span> {
<span class=nb>name</span> = <span class=s>"sandbox-vpn"</span>
}
</code></pre></div>
<p>This only requires a few prerequisites to be in place:</p>
<ul>
<li>A Tailscale <a href="https://tailscale.com/kb/1085/auth-keys/">auth key</a> stored in an AWS Secrets Manager secret</li>
<li>A Docker image tagged and pushed to ECR for running your subnet router; we
have provided a <a href="https://github.com/hardfinhq/terraform-aws-tailscale-subnet-router/blob/v1.20220802.1/_docker/tailscale.Dockerfile">Dockerfile</a> you can use</li>
<li>The core foundation needed for an ECS cluster that can schedule Fargate tasks
(i.e. the cluster, a VPC, subnets, security groups, etc.)</li>
</ul>
<h2>Onwards</h2>
<p>We'd love to continue the discussion <a href="https://github.com/hardfinhq/terraform-aws-tailscale-subnet-router/issues/new">on GitHub</a>. Feature requests and pull
requests are welcome! For the initial release, the module is very much scoped to
our internal networks at Hardfin but we'd be happy to make the module more
configurable to make it accessible to a broader audience. There are a few
<a href="https://github.com/hardfinhq/terraform-aws-tailscale-subnet-router/tree/v1.20220802.1#room-for-improvement">suggestions</a> already in the repository as a starting point for ways to
help adapt the module to other engineering organizations.</p><ol class=simple-footnotes><li id=sf-tailscale-terraform-fargate-1>Or your <code>100.x.y.z</code> <a href="https://tailscale.com/kb/1015/100.x-addresses/">Tailscale IP</a> if
you'd like to be more surgical when binding to network interfaces. <a href=#sf-tailscale-terraform-fargate-1-back class=simple-footnote-back>↩</a></li><li id=sf-tailscale-terraform-fargate-2>Our founding team has deep experience with Kubernetes as well but
chose not to use it because of the operational burden. An ECS task definition is
<strong>very</strong> similar to a Kubernetes pod spec already, so we get many of the same
benefits afforded by Kubernetes. <a href=#sf-tailscale-terraform-fargate-2-back class=simple-footnote-back>↩</a></li></ol>What npm Can Learn from Go2022-05-26T00:00:00-07:002022-05-26T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2022-05-26:/2022/05/npm-mod.html<div style="text-align: center;">
<p><img alt="npm and Go" src="/images/npm-and-go.png"></p>
</div>
<blockquote>
<p>This is cross-posted from the Hardfin engineering <a href="https://engineering.hardfin.com/2022/05/npm-mod/">blog</a>.</p>
</blockquote>
<p>As programming language ecosystems evolve, they learn from each other. When this
happens we all benefit from more useful features, patterns, libraries, and
tools. A core part of a programming language ecosystem — packaging —
can be a source of pain, e.g. from …</p><div style="text-align: center;">
<p><img alt="npm and Go" src="/images/npm-and-go.png"></p>
</div>
<blockquote>
<p>This is cross-posted from the Hardfin engineering <a href="https://engineering.hardfin.com/2022/05/npm-mod/">blog</a>.</p>
</blockquote>
<p>As programming language ecosystems evolve, they learn from each other. When this
happens we all benefit from more useful features, patterns, libraries, and
tools. A core part of a programming language ecosystem — packaging —
can be a source of pain, e.g. from version <a href="https://medium.com/knerd/the-nine-circles-of-python-dependency-hell-481d53e3e025">conflicts</a>, slow <a href="https://fasterthanli.me/articles/why-is-my-rust-build-so-slow">build</a>
times, security <a href="https://www.synopsys.com/blogs/software-security/malicious-dependency-supply-chain/">issues</a>, etc.</p>
<p>At Hardfin we are happy users of both Go and TypeScript. We love the wealth of
useful packages in the <code>npm</code> ecosystem that help us build modern web
applications. There are a few common patterns in the Go packaging landscape that
don't translate to the <code>npm</code> packaging experience, but we would love it if they
did! In this post we'll introduce a tool that exemplifies language ecosystem
cross pollination. This tool is a minimal implementation of an experiment to
bring the benefits of Go package vendoring to the <code>npm</code> ecosystem.</p>
<h2>Stuck on an airplane</h2>
<p>Alice is scrambling to leave her apartment for a flight that takes off in less
than an hour. She wants to get familiar with the application her new team
maintains, so she clones the repo in a hurry before packing her laptop. In a mad
dash she <strong>just</strong> manages to board the plane before the gate closes. Finally
with a chance to collect herself and breathe, she opens her laptop and gets
ready to start coding.</p>
<p>After reading the team's getting started document, she hops into the backend
code and fires up the server:</p>
<div class=highlight><pre><span></span><code>go run ./cmd/feather-server/main.go
</code></pre></div>
<p>Now that the backend is running, she moves on to the frontend instructions in
the getting started document. Unfortunately, this is a roadblock that she'll
need inflight Wi-Fi to overcome. To build and run the frontend, she first
needs to install all dependencies:</p>
<div class=highlight><pre><span></span><code>npm ci
npm run feather-app
</code></pre></div>
<p>Meanwhile on the ground, Alice's new teammates Eve and Trudy are struggling to
understand why the frontend build caused the latest production deploy to fail.
It's very unfortunate timing — they are trying to ship a new feature as
part of a customer demo.</p>
<p>There were no signs of trouble in the latest merged pull request; all CI checks
passed. But the build is failing to install dependencies with:</p>
<div class=highlight><pre><span></span><code>$ npm ci
npm ERR! code E404
npm ERR! <span class=m>404</span> Not Found - GET https://registry.npmjs.org/skugga/-/skugga-9.1.1.tgz - Not found
npm ERR! <span class=m>404</span>
npm ERR! <span class=m>404</span> <span class=s1>'skugga@https://registry.npmjs.org/skugga/-/skugga-9.1.1.tgz'</span> is not <span class=k>in</span> this registry.
npm ERR! <span class=m>404</span>
npm ERR! <span class=m>404</span> Note that you can also install from a
npm ERR! <span class=m>404</span> tarball, folder, http url, or git url.
npm ERR! A <span class=nb>complete</span> log of this run can be found <span class=k>in</span>:
npm ERR! /root/.npm/_logs/2022-04-29T16_20_17_523Z-debug-0.log
</code></pre></div>
<p>After 30 minutes of scrambling and head scratching, they hop on Twitter and from
reading posts in their timeline they realize the author of <code>skugga</code> has removed
the package entirely from the package registry.</p>
<h2>Why airplane mode for dependencies?</h2>
<p>Why was Alice able to start the Go backend after <strong>only</strong> just cloning the
repository? Her team <a href="https://go.dev/ref/mod#go-mod-vendor">uses</a> <code>go mod vendor</code> and checks in the root
<code>vendor/</code> directory to the codebase. This means that after <code>git clone</code>, all
application binaries can be built by the Go compiler — no dependencies to
fetch, no inflight Wi-Fi necessary! In addition to enabling airplane mode,
there are several other benefits<sup id=sf-npm-mod-1-back><a href=#sf-npm-mod-1 class=simple-footnote title="The primary downside of checking in vendor/ is a larger git checkout.">1</a></sup> from checking in the <code>vendor/</code>
directory:</p>
<ul>
<li>New dependencies show up in pull requests as changes to <code>vendor/</code>; the
larger the diff, the more "weight" that the dependency adds</li>
<li>All builds (Docker and otherwise) are hermetic and don't require
fetching packages from the public internet<sup id=sf-npm-mod-2-back><a href=#sf-npm-mod-2 class=simple-footnote title="Mostly hermetic. This really only applies to the components of the build containing Go or TypeScript code (and packages).">2</a></sup></li>
<li>Even if dependencies are <a href="https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code/">deleted</a> by a third party, this won't impact
the current codebase (avoiding the
"my code didn't change but it stopped working!" crisis that Eve and Trudy
are in)</li>
<li>Fully consistent development environments for all team members (without
need for consistent <code>~/.npm/_cacache</code>, <code>~/Library/Caches/Yarn/v6</code>, etc.)</li>
<li>Supply chain <a href="https://jfrog.com/blog/npm-supply-chain-attack-targets-german-based-companies/">attacks</a> cannot impact the dependencies without making it
into a pull request</li>
</ul>
<h2>Switching <code>npm</code> into airplane mode</h2>
<p>In order to bring the <code>go mod vendor</code> experience to the <code>npm</code> ecosystem, we've
created an experimental CLI <a href="https://github.com/hardfinhq/npm-mod">tool</a> called <code>npm-mod</code>. Using the tool, Alice
can download all package tarballs into the <code>vendor/</code> directory and change the
application's <code>package.json</code> and <code>package-lock.json</code> so that all <strong>remote</strong>
package references are replaced with local file references.</p>
<div class=highlight><pre><span></span><code>$ npm-mod tidy
$ npm-mod vendor
Saved babel__helper-builder-binary-assignment-operator-visitor-7.16.7.tgz
Saved babel__generator-7.17.9.tgz
...
$
$ ls -1 vendor/
abab-2.0.6.tgz
...
$ ls -1 vendor/ <span class=p>|</span> wc -l
<span class=m>1135</span>
</code></pre></div>
<p>After running this, both <code>package.json</code> and <code>package-lock.json</code> will be
changed and a new <code>.npm-mod.tidy.json</code> file will be added:</p>
<div class=highlight><pre><span></span><code><span class=gh>diff --git a/package-lock.json b/package-lock.json</span>
<span class=gh>index 5303979..02c30e9 100644</span>
<span class=gd>--- a/package-lock.json</span>
<span class=gi>+++ b/package-lock.json</span>
<span class=gu>@@ -18,8 +18,8 @@</span>
}
},
"node_modules/@ampproject/remapping": {
<span class=gd>- "version": "2.1.2",</span>
<span class=gd>- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz",</span>
<span class=gi>+ "version": "file:vendor/ampproject__remapping-2.1.2.tgz",</span>
<span class=gi>+ "resolved": "file:vendor/ampproject__remapping-2.1.2.tgz",</span>
"integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.0"
<span class=gu>@@ -29,8 +29,8 @@</span>
...
<span class=gh>diff --git a/package.json b/package.json</span>
<span class=gh>index 82115d2..753457c 100644</span>
<span class=gd>--- a/package.json</span>
<span class=gi>+++ b/package.json</span>
<span class=gu>@@ -3,13 +3,13 @@</span>
"version": "0.0.1",
"private": true,
"dependencies": {
<span class=gd>- "@testing-library/jest-dom": "^5.16.4",</span>
<span class=gd>- "@testing-library/react": "^13.1.1",</span>
<span class=gd>- "@testing-library/user-event": "^13.5.0",</span>
<span class=gd>- "react": "^18.0.0",</span>
<span class=gd>- "react-dom": "^18.0.0",</span>
<span class=gd>- "react-scripts": "5.0.1",</span>
<span class=gd>- "web-vitals": "^2.1.4"</span>
<span class=gi>+ "@testing-library/jest-dom": "file:vendor/testing-library__jest-dom-5.16.4.tgz",</span>
<span class=gi>+ "@testing-library/react": "file:vendor/testing-library__react-13.1.1.tgz",</span>
<span class=gi>+ "@testing-library/user-event": "file:vendor/testing-library__user-event-13.5.0.tgz",</span>
<span class=gi>+ "react": "file:vendor/react-18.0.0.tgz",</span>
<span class=gi>+ "react-dom": "file:vendor/react-dom-18.0.0.tgz",</span>
<span class=gi>+ "react-scripts": "file:vendor/react-scripts-5.0.1.tgz",</span>
<span class=gi>+ "web-vitals": "file:vendor/web-vitals-2.1.4.tgz"</span>
},
"scripts": {
"start": "react-scripts start",
</code></pre></div>
<h2>The next flight: future work</h2>
<p>After doing this, Alice can happily install all of the <code>npm</code> packages for her
team's application without any internet connection:</p>
<div class=highlight><pre><span></span><code>$ ping hardfin.com
ping: cannot resolve hardfin.com: Unknown host
$
$ <span class=nb>time</span> npm ci
...
added <span class=m>1393</span> packages, and audited <span class=m>1394</span> packages <span class=k>in</span> 4s
...
real 0m4.456s
user 0m5.112s
sys 0m5.802s
</code></pre></div>
<p>This is still an experiment and we'd want to see some improvements before
recommending <code>npm-mod</code> as a core part of your team's workflow:</p>
<ul>
<li>This tool is intended for <strong>applications</strong>, it should not be used for a
library published to a package registry.</li>
<li>The vendoring process should hook into <code>npm audit</code> (<a href="https://overreacted.io/npm-audit-broken-by-design/">problems</a> with
<code>npm audit</code> notwithstanding).</li>
<li>The existence of <code>npm</code> install scripts still poses a large security
concern. There is a growing <a href="https://github.com/npm/rfcs/pull/488">movement</a> to disable install scripts.</li>
<li>Though the <code>vendor/</code> approach mitigates supply chain "denial of service"
attacks like the <code>colors</code> <a href="https://research.swtch.com/npm-colors">incident</a>, actually <strong>catching</strong> instances
of this during code review is still a challenge if the only artifacts
checked into the <code>vendor/</code> directory are tarballs.</li>
<li>There is no <code>npm</code> equivalent of the Go build cache (<code>go env GOCACHE</code>);
if the same Go package is built multiple times, the previous builds can
be reused. The nearest equivalent is the presence of the same
(already installed) package in <code>node_modules/</code>.</li>
</ul>
<h2>Landing the plane</h2>
<p>We'd love to continue the <a href="https://github.com/hardfinhq/npm-mod/issues">discussion</a> and improve <code>npm-mod</code> to a point
where teams like Alice's and our own are comfortable using it in daily
workflows. By adopting this workflow and gaining airplane mode, teams can
avoid unexpected breakages and ensure <strong>all</strong> code required to build the
repo is present after checkout.</p>
<p>In addition to the tooling, there is a cultural norm in the Go community
of viewing new dependencies with skepticism. This is captured by a
<a href="https://go-proverbs.github.io/">Go proverb</a>: A little copying is better than a little dependency.
Checking application dependencies into the codebase means they are front
and center, both for security and for their contents. In addition to enabling
airplane mode, we hope that by vendoring the <a href="https://twitter.com/acdlite/status/1483223737424130048">weight</a> of dependencies starts
to get more consideration.</p>
<div style="text-align: center;">
<p><img alt="Gopher Landing" src="/images/gopher-biplane.jpg"></p>
</div><ol class=simple-footnotes><li id=sf-npm-mod-1>The primary <a href="https://penkovski.com/post/to-vendor-or-not-to-vendor/">downside</a> of checking in
<code>vendor/</code> is a larger <code>git</code> checkout. <a href=#sf-npm-mod-1-back class=simple-footnote-back>↩</a></li><li id=sf-npm-mod-2><strong>Mostly</strong> hermetic. This
really only applies to the components of the build containing Go or
TypeScript code (and packages). <a href=#sf-npm-mod-2-back class=simple-footnote-back>↩</a></li></ol>Emulating RDS Permissions with Terraform2022-04-04T00:00:00-07:002022-04-04T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2022-04-04:/2022/04/emulate-rds-permissions.html<div style="text-align: center;">
<p><img alt="Terraform, PostgreSQL and RDS" src="/images/terraform-postgresql-and-rds.png"></p>
</div>
<blockquote>
<p>This is cross-posted from the Hardfin engineering <a href="https://engineering.hardfin.com/2022/04/emulate-rds-permissions/">blog</a>.</p>
</blockquote>
<p>At Hardfin, we use AWS RDS for managed PostgreSQL instances to simplify our
infrastructure and focus on product. For the most part, RDS is
"just PostgreSQL" and acts like the PostgreSQL instances that we run on our
development machines. Unfortunately, it differs …</p><div style="text-align: center;">
<p><img alt="Terraform, PostgreSQL and RDS" src="/images/terraform-postgresql-and-rds.png"></p>
</div>
<blockquote>
<p>This is cross-posted from the Hardfin engineering <a href="https://engineering.hardfin.com/2022/04/emulate-rds-permissions/">blog</a>.</p>
</blockquote>
<p>At Hardfin, we use AWS RDS for managed PostgreSQL instances to simplify our
infrastructure and focus on product. For the most part, RDS is
"just PostgreSQL" and acts like the PostgreSQL instances that we run on our
development machines. Unfortunately, it differs in a few key ways —
and that opens the door for dreaded "it works on my machine" issues.</p>
<p>We recently encountered a surprising error in RDS, which we couldn't replicate
in our local development setup. In order to prevent future issues like
this, we took steps to make our Dockerized PostgreSQL instance much more
similar to an RDS instance.</p>
<p>We are big proponents of Infrastructure-as-Code at Hardfin. We utilize
<a href="https://www.terraform.io/">Terraform</a> to describe as much of our infrastructure as we can, including
AWS RDS instances running PostgreSQL.</p>
<p>In addition to AWS resources, we use Terraform to directly manage some
PostgreSQL resources. A fresh RDS instance comes with a single role (the RDS
master user) available to DB operators. We <strong>only</strong> use this this RDS master
user via the <a href="https://registry.terraform.io/providers/cyrilgdn/postgresql">PostgreSQL provider</a> to create new application roles with
minimal privileges.</p>
<h2>Getting locked out</h2>
<p>RDS <a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.MasterAccounts.html">best practices</a> recommend against using the RDS master user within
applications; it has elevated privileges beyond what applications should be able
to do.</p>
<p>As part of scoping a minimal set of privileges, we utilize grants to create
(1) an admin role used during migrations and other offline operations, and,
(2) an application role used directly while running the application. The admin
role permissions allow a full set of <a href="https://en.wikipedia.org/wiki/Data_definition_language">DDL</a> operations while the application
role has a scope limited to <a href="https://en.wikipedia.org/wiki/Data_manipulation_language">DML</a> operations.</p>
<p>As part of the process of limiting access, we merged a change to limit which
roles can <code>CONNECT</code> to a PostgreSQL <code>DATABASE</code> and to even further limit which
roles can <code>CREATE</code> in the <code>DATABASE</code>. After running this against a Dockerized
PostgreSQL instance used for local development, all changes were applied
successfully.</p>
<p>Once unit tests passed in CI, we merged the change and ran the Terraform plan in
our <code>sandbox</code> environment against an actual RDS instance. These changes too were
applied successfully, or so we thought. Later that day, another small change was
made to the same Terraform workspace. With no signs of trouble in testing, this
change was merged. When we went to generate a plan in <code>sandbox</code>, we found out
the RDS master user was <strong>locked out</strong>:</p>
<div class=highlight><pre><span></span><code>$ terraform apply
...
postgresql_grant.revoke_public: Refreshing state... <span class=o>[</span><span class=nv>id</span><span class=o>=</span>public_initech_database<span class=o>]</span>
...
╷
│ Error: error detecting capabilities: error PostgreSQL version: pq: permission denied <span class=k>for</span> database <span class=s2>"initech"</span>
│
│ with postgresql_grant.revoke_public,
│ on grants.tf line <span class=m>6</span>, <span class=k>in</span> resource <span class=s2>"postgresql_grant"</span> <span class=s2>"revoke_public"</span>:
│ <span class=m>6</span>: resource <span class=s2>"postgresql_grant"</span> <span class=s2>"revoke_public"</span> <span class=o>{</span>
│
╵
...
</code></pre></div>
<h2>What went wrong</h2>
<p>The RDS master user got locked out as a result of a change that introduced
three <code>DATABASE</code> grants:</p>
<div class=highlight><pre><span></span><code><span class=nv>resource</span> <span class=s2>"</span><span class=s>postgresql_grant</span><span class=s2>"</span> <span class=s2>"</span><span class=s>revoke_public</span><span class=s2>"</span> {
<span class=nv>database</span> <span class=o>=</span> <span class=nv>postgresql_database</span>.<span class=nv>initech</span>.<span class=nv>name</span>
<span class=nv>role</span> <span class=o>=</span> <span class=s2>"</span><span class=s>public</span><span class=s2>"</span>
<span class=nv>object_type</span> <span class=o>=</span> <span class=s2>"</span><span class=s>database</span><span class=s2>"</span>
<span class=nv>privileges</span> <span class=o>=</span> []
}
<span class=nv>resource</span> <span class=s2>"</span><span class=s>postgresql_grant</span><span class=s2>"</span> <span class=s2>"</span><span class=s>app_role_connect</span><span class=s2>"</span> {
<span class=nv>database</span> <span class=o>=</span> <span class=nv>postgresql_database</span>.<span class=nv>initech</span>.<span class=nv>name</span>
<span class=nv>role</span> <span class=o>=</span> <span class=nv>postgresql_role</span>.<span class=nv>app_role_gibbons</span>.<span class=nv>name</span>
<span class=nv>object_type</span> <span class=o>=</span> <span class=s2>"</span><span class=s>database</span><span class=s2>"</span>
<span class=nv>privileges</span> <span class=o>=</span> [<span class=s2>"</span><span class=s>CONNECT</span><span class=s2>"</span>]
}
<span class=nv>resource</span> <span class=s2>"</span><span class=s>postgresql_grant</span><span class=s2>"</span> <span class=s2>"</span><span class=s>admin_role_full</span><span class=s2>"</span> {
<span class=nv>database</span> <span class=o>=</span> <span class=nv>postgresql_database</span>.<span class=nv>initech</span>.<span class=nv>name</span>
<span class=nv>role</span> <span class=o>=</span> <span class=nv>postgresql_role</span>.<span class=nv>admin_role_lumbergh</span>.<span class=nv>name</span>
<span class=nv>object_type</span> <span class=o>=</span> <span class=s2>"</span><span class=s>database</span><span class=s2>"</span>
<span class=nv>privileges</span> <span class=o>=</span> [<span class=s2>"</span><span class=s>CREATE</span><span class=s2>"</span>, <span class=s2>"</span><span class=s>TEMPORARY</span><span class=s2>"</span>, <span class=s2>"</span><span class=s>CONNECT</span><span class=s2>"</span>]
}
</code></pre></div>
<p>After applying, only the admin and application role were allowed to connect
to the database<sup id=sf-emulate-rds-permissions-1-back><a href=#sf-emulate-rds-permissions-1 class=simple-footnote title="The DATABASE privileges (e.g. lumbergh=CTc/lumbergh+) corresponds to CREATE (C), TEMPORARY (T) and CONNECT (c).">1</a></sup>:</p>
<div class=highlight><pre><span></span><code><span class=n>initech</span><span class=o>=></span> <span class=err>\</span><span class=n>l</span> <span class=n>initech</span>
<span class=n>List</span> <span class=k>of</span> <span class=n>databases</span>
<span class=n>Name</span> <span class=o>|</span> <span class=k>Owner</span> <span class=o>|</span> <span class=k>Encoding</span> <span class=o>|</span> <span class=k>Collate</span> <span class=o>|</span> <span class=n>Ctype</span> <span class=o>|</span> <span class=k>Access</span> <span class=k>privileges</span>
<span class=c1>---------+----------+----------+-------------+-------------+-----------------------</span>
<span class=n>initech</span> <span class=o>|</span> <span class=n>lumbergh</span> <span class=o>|</span> <span class=n>UTF8</span> <span class=o>|</span> <span class=n>en_US</span><span class=p>.</span><span class=n>UTF</span><span class=o>-</span><span class=mi>8</span> <span class=o>|</span> <span class=n>en_US</span><span class=p>.</span><span class=n>UTF</span><span class=o>-</span><span class=mi>8</span> <span class=o>|</span> <span class=n>lumbergh</span><span class=o>=</span><span class=n>CTc</span><span class=o>/</span><span class=n>lumbergh</span><span class=o>+</span>
<span class=o>|</span> <span class=o>|</span> <span class=o>|</span> <span class=o>|</span> <span class=o>|</span> <span class=n>gibbons</span><span class=o>=</span><span class=k>c</span><span class=o>/</span><span class=n>lumbergh</span>
<span class=p>(</span><span class=mi>1</span> <span class=k>row</span><span class=p>)</span>
</code></pre></div>
<p>Crucially, this list does not include the RDS master user:</p>
<div class=highlight><pre><span></span><code>$ <span class=nv>PGPASSWORD</span><span class=o>=</span><span class=k>$(</span>cat ./very-secret.txt<span class=k>)</span> psql <span class=se>\</span>
> <span class=s2>"postgres://initech_master_user@initech-sandbox.cthulhu2hyup.zz-outercentral-7.rds.amazonaws.com:5432/initech"</span>
psql: error: connection to server at <span class=s2>"initech-sandbox.cthulhu2hyup.zz-outercentral-7.rds.amazonaws.com"</span> <span class=o>(</span><span class=m>10</span>.54.42.10<span class=o>)</span>, port <span class=m>5432</span> failed: FATAL: permission denied <span class=k>for</span> database <span class=s2>"initech"</span>
DETAIL: User does not have CONNECT privilege.
</code></pre></div>
<h2>Detecting issues locally</h2>
<p>We never detected this <code>CONNECT</code> issue because we were using a superuser in our
Dockerized PostgreSQL instance during local development with the Terraform
<a href="https://registry.terraform.io/providers/cyrilgdn/postgresql">provider</a>. A superuser can <strong>never</strong> get locked out because it can do
anything and everything in the PostgreSQL instance.</p>
<p>To fix this, we introduced an equivalent to the RDS master user locally and
stopped using the superuser from Terraform. After switching to this user
in the Terraform provider, we were able to replicate the <code>CONNECT</code> issue.</p>
<p>To create the RDS master user locally, we jumped on an RDS instance and examined
the attributes of the RDS master user:</p>
<div class=highlight><pre><span></span><code><span class=n>initech</span><span class=o>=></span> <span class=err>\</span><span class=n>du</span> <span class=n>initech_master_user</span>
<span class=n>List</span> <span class=k>of</span> <span class=n>roles</span>
<span class=k>Role</span> <span class=n>name</span> <span class=o>|</span> <span class=n>Attributes</span> <span class=o>|</span> <span class=n>Member</span> <span class=k>of</span>
<span class=c1>---------------------+-------------------------------+-----------------</span>
<span class=n>initech_master_user</span> <span class=o>|</span> <span class=k>Create</span> <span class=k>role</span><span class=p>,</span> <span class=k>Create</span> <span class=n>DB</span> <span class=o>+|</span> <span class=err>{</span><span class=n>rds_superuser</span><span class=err>}</span>
<span class=o>|</span> <span class=n>Password</span> <span class=k>valid</span> <span class=k>until</span> <span class=n>infinity</span> <span class=o>|</span>
<span class=n>initech</span><span class=o>=></span> <span class=k>SELECT</span> <span class=o>*</span> <span class=k>FROM</span> <span class=n>pg_catalog</span><span class=p>.</span><span class=n>pg_roles</span> <span class=k>WHERE</span> <span class=n>rolname</span> <span class=o>=</span> <span class=s1>'initech_master_user'</span><span class=p>;</span>
<span class=n>rolname</span> <span class=o>|</span> <span class=n>rolsuper</span> <span class=o>|</span> <span class=n>rolinherit</span> <span class=o>|</span> <span class=n>rolcreaterole</span> <span class=o>|</span> <span class=n>rolcreatedb</span> <span class=o>|</span> <span class=n>rolcanlogin</span> <span class=o>|</span> <span class=n>rolreplication</span> <span class=o>|</span> <span class=n>rolconnlimit</span> <span class=o>|</span> <span class=n>rolpassword</span> <span class=o>|</span> <span class=n>rolvaliduntil</span> <span class=o>|</span> <span class=n>rolbypassrls</span> <span class=o>|</span> <span class=n>rolconfig</span> <span class=o>|</span> <span class=n>oid</span>
<span class=c1>---------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+-------</span>
<span class=n>initech_master_user</span> <span class=o>|</span> <span class=n>f</span> <span class=o>|</span> <span class=n>t</span> <span class=o>|</span> <span class=n>t</span> <span class=o>|</span> <span class=n>t</span> <span class=o>|</span> <span class=n>t</span> <span class=o>|</span> <span class=n>f</span> <span class=o>|</span> <span class=o>-</span><span class=mi>1</span> <span class=o>|</span> <span class=o>********</span> <span class=o>|</span> <span class=n>infinity</span> <span class=o>|</span> <span class=n>f</span> <span class=o>|</span> <span class=o>|</span> <span class=mi>13370</span>
<span class=p>(</span><span class=mi>1</span> <span class=k>row</span><span class=p>)</span>
</code></pre></div>
<p>Using this information, we created an SQL file (<code>rds_master_user.sql</code>) to
create this role in the Dockerized PostgreSQL instance:</p>
<div class=highlight><pre><span></span><code><span class=k>CREATE</span> <span class=k>ROLE</span> <span class=n>initech_master_user</span>
<span class=k>WITH</span> <span class=k>ENCRYPTED</span> <span class=n>PASSWORD</span> <span class=s1>'...'</span>
<span class=k>VALID</span> <span class=k>UNTIL</span> <span class=s1>'infinity'</span>
<span class=n>NOSUPERUSER</span>
<span class=n>INHERIT</span>
<span class=n>CREATEROLE</span>
<span class=k>CREATEDB</span>
<span class=n>LOGIN</span>
<span class=n>NOREPLICATION</span>
<span class=k>CONNECTION</span> <span class=k>LIMIT</span> <span class=o>-</span><span class=mi>1</span>
<span class=n>NOBYPASSRLS</span><span class=p>;</span>
</code></pre></div>
<p>In order to ensure this role gets created during PostgreSQL startup, we
volume mount it at <code>/docker-entrypoint-initdb.d/rds_master_user.sql</code>.</p>
<h2>Fixing the issue</h2>
<p>In order to fix the broken RDS instance, we temporarily granted the admin
role to the RDS master user:</p>
<div class=highlight><pre><span></span><code><span class=k>GRANT</span> <span class=n>lumbergh</span> <span class=k>TO</span> <span class=n>initech_master_user</span><span class=p>;</span>
<span class=c1>-- AFTER: REVOKE lumbergh FROM initech_master_user;</span>
</code></pre></div>
<p>and made sure the master user could connect as well:</p>
<div class=highlight><pre><span></span><code><span class=nv>locals</span> {
<span class=nv>aws_master_user</span> <span class=o>=</span> <span class=s2>"</span><span class=s>initech_master_user</span><span class=s2>"</span>
}
<span class=nv>resource</span> <span class=s2>"</span><span class=s>postgresql_grant</span><span class=s2>"</span> <span class=s2>"</span><span class=s>aws_master_user_connect</span><span class=s2>"</span> {
<span class=nv>database</span> <span class=o>=</span> <span class=nv>postgresql_database</span>.<span class=nv>initech</span>.<span class=nv>name</span>
<span class=nv>role</span> <span class=o>=</span> <span class=nv>local</span>.<span class=nv>aws_master_user</span>
<span class=nv>object_type</span> <span class=o>=</span> <span class=s2>"</span><span class=s>database</span><span class=s2>"</span>
<span class=nv>privileges</span> <span class=o>=</span> [<span class=s2>"</span><span class=s>CONNECT</span><span class=s2>"</span>]
}
</code></pre></div>
<h2>Conclusion</h2>
<p>Subtle behavior differences between local development and production can lead to
not-so-subtle issues. There is a long tail of problems that can arise if the
development setup is too different, particularly issues around permissions.</p>
<p>Emulating the PostgreSQL RDS master user allows Terraform to manage roles
locally in the same way they are managed in production. This is just one of many
changes needed to make the local development database faithful to production.
Luckily, using Terraform locally allows us to bridge <strong>many</strong> other gaps by
giving us the same roles and grants that we have in RDS.</p>
<div style="text-align: center;">
<p><img alt="Bill Lumbergh; Initech" src="/images/lumbergh.png"></p>
</div><ol class=simple-footnotes><li id=sf-emulate-rds-permissions-1>The <code>DATABASE</code> privileges (e.g. <code>lumbergh=CTc/lumbergh+</code>)
corresponds to CREATE (<code>C</code>), TEMPORARY (<code>T</code>) and CONNECT (<code>c</code>). <a href=#sf-emulate-rds-permissions-1-back class=simple-footnote-back>↩</a></li></ol>Epitaph: Blend2022-03-04T00:00:00-08:002022-03-04T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2022-03-04:/2022/03/blend-epitaph.html<div style="text-align: center;">
<p><img alt="Auf Wiedersehen" src="/images/so-long-farewell.jpg"></p>
</div>
<h3>Goodbye</h3>
<p>I recently made the <strong>very hard</strong> decision to leave <a href="https://blend.com/">Blend</a>. Today
(March 4, 2022) is my last day. I am overwhelmed with emotion thinking about
all of the amazing people I worked with and projects I worked on at Blend.
I want to thank you all from the bottom …</p><div style="text-align: center;">
<p><img alt="Auf Wiedersehen" src="/images/so-long-farewell.jpg"></p>
</div>
<h3>Goodbye</h3>
<p>I recently made the <strong>very hard</strong> decision to leave <a href="https://blend.com/">Blend</a>. Today
(March 4, 2022) is my last day. I am overwhelmed with emotion thinking about
all of the amazing people I worked with and projects I worked on at Blend.
I want to thank you all from the bottom of my heart, it has meant the world
to me.</p>
<p>After finishing my PhD I had a standing job offer to return to Google, but
decided to take a leap at Blend and learn something new. Boy did I ever! I
spent just over three years at Blend but I feel like by moving at startup speed
I gained ten years of indispensable experience.</p>
<p>I've seen the incredible impact that comes from meeting a customer need. In
my early time here on a product team, we saw a quarter's worth of effort turn
into huge increases in utilization for our target customers.</p>
<p>I've directly witnessed the growing pains that come with hockey stick growth
and the heroic efforts to scale systems, databases and people. Hearing
motivational speeches from our leaders is one thing, but watching the scale of
our compute grow as our product continued to gain traction was the most
motivating thing of all for me<sup id=sf-blend-epitaph-1-back><a href=#sf-blend-epitaph-1 class=simple-footnote title="Especially when followed by talks from finance showing revenue growth that tracked the growth in compute.">1</a></sup>!</p>
<p>Though it is already a publicly traded, multibillion dollar company, Blend
is still a very young company. That means everyone still gets the chance to
influence the culture at Blend and set the standards in Blend engineering for
the future. This was and is incredibly compelling to me<sup id=sf-blend-epitaph-2-back><a href=#sf-blend-epitaph-2 class=simple-footnote title="Each of the teammates that I've helped hire can attest that I make this pitch during the interview process.">2</a></sup>!</p>
<h3>What's Next?</h3>
<p>I am not running away from Blend, I am running towards a new opportunity. I
am starting a company with two close friends. I have been fascinated with
company building since early in my career and am excited to begin the journey
of growing my very own startup.</p>
<h3>So Long, and Thanks for All the Fish</h3>
<div style="text-align: center;">
<p><img alt="Thanks for All the Fish" src="/images/so-long.gif"></p>
</div>
<hr style="margin-bottom: 25px; width: 50%;"><ol class=simple-footnotes><li id=sf-blend-epitaph-1>Especially when followed by talks from
finance showing revenue growth that tracked the growth in compute. <a href=#sf-blend-epitaph-1-back class=simple-footnote-back>↩</a></li><li id=sf-blend-epitaph-2>Each of
the teammates that I've helped hire can attest that I make this pitch during
the interview process. <a href=#sf-blend-epitaph-2-back class=simple-footnote-back>↩</a></li></ol>How to Write GitHub Actions in Go2022-02-07T00:00:00-08:002022-02-07T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2022-02-07:/2022/02/how-to-write-github-actions-in-go.html<p><img alt="Go with GitHub Actions" src="/images/go-with-github-actions.png"></p>
<p>I recently<sup id=sf-how-to-write-github-actions-in-go-1-back><a href=#sf-how-to-write-github-actions-in-go-1 class=simple-footnote title="It was recent when I wrote this on February 7, 2022.">1</a></sup> had
the privilege of co-authoring a blog post on the Blend <a href="https://full-stack.blend.com/">engineering blog</a>
with my esteemed colleague <a href="https://github.com/thomasnotfound">Thomas Taylor</a>. I copied this content over
mostly as-is from the <a href="https://full-stack.blend.com/how-we-write-github-actions-in-go.html">original post</a> but wanted to preserve it here as
well.</p>
<h3>Contents</h3>
<ul>
<li><a href=#introduction>Introduction</a></li>
<li><a href=#authoring-an-action>Authoring an Action: Today's Landscape</a></li>
<li><a href=#how-we-release>How We …</a></li></ul><p><img alt="Go with GitHub Actions" src="/images/go-with-github-actions.png"></p>
<p>I recently<sup id=sf-how-to-write-github-actions-in-go-1-back><a href=#sf-how-to-write-github-actions-in-go-1 class=simple-footnote title="It was recent when I wrote this on February 7, 2022.">1</a></sup> had
the privilege of co-authoring a blog post on the Blend <a href="https://full-stack.blend.com/">engineering blog</a>
with my esteemed colleague <a href="https://github.com/thomasnotfound">Thomas Taylor</a>. I copied this content over
mostly as-is from the <a href="https://full-stack.blend.com/how-we-write-github-actions-in-go.html">original post</a> but wanted to preserve it here as
well.</p>
<h3>Contents</h3>
<ul>
<li><a href=#introduction>Introduction</a></li>
<li><a href=#authoring-an-action>Authoring an Action: Today's Landscape</a></li>
<li><a href=#how-we-release>How We Release Actions in Go</a></li>
<li><a href=#how-we-write>How We Write Actions in Go</a></li>
<li><a href=#why-not-docker>Why Not Docker?</a></li>
<li><a href=#conclusion>Conclusion</a></li>
</ul>
<h3 id=introduction>Introduction</h3>
<p>Since the <a href="https://github.blog/2019-08-08-github-actions-now-supports-ci-cd/">release</a> of GitHub Actions in 2019, GitHub has been heavily
investing in improvements to the CI / CD experience. As part of this
investment, repeatable tasks can be provided as <a href="https://docs.github.com/en/actions/creating-actions/about-custom-actions">custom actions</a> and
shared externally with the community or internally within a GitHub Enterprise
instance.</p>
<p>At Blend, we've benefited from adopting GitHub Actions. We have built
tooling that enables writing an action in Go and automates the release
process for actions within our GitHub Enterprise instance. Below, we'll share
the set of unique challenges for running and releasing actions written in Go
and outline our strategies for solving these problems.</p>
<h3 id=authoring-an-action>Authoring an Action: Today's Landscape</h3>
<p>GitHub has published lots of tutorials and many fundamental
actions<sup id=sf-how-to-write-github-actions-in-go-2-back><a href=#sf-how-to-write-github-actions-in-go-2 class=simple-footnote title="For example, using actions/checkout to checkout code and actions/cache to cache dependencies to speed up CI runs.">2</a></sup> as
examples. In order to let the community use the same tools, they have released
the <code>@actions/core</code> <a href="https://www.npmjs.com/package/@actions/core">package</a> on <code>npm</code>.</p>
<p>An action is a GitHub repository with a root
<code>action.yml</code> file and supporting files. For authors of an action,
the most common choice is to write it <a href="https://docs.github.com/en/actions/creating-actions/creating-a-javascript-action">in JavaScript</a> and run the code
natively on the actions runner during the workflow. If that isn't an
option<sup id=sf-how-to-write-github-actions-in-go-3-back><a href=#sf-how-to-write-github-actions-in-go-3 class=simple-footnote title="E.g. for teams that prefer something other than JavaScript.">3</a></sup>, a
<a href="https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action">Docker container action</a> allows running a Docker image; the image can
either be built directly from a Dockerfile or pulled from a public Docker
registry.</p>
<p>The third option, a <a href="https://docs.github.com/en/actions/creating-actions/creating-a-composite-action">composite</a> action, allows
creating an action as a series of steps (very similar to how jobs work in
a GitHub Actions workflow). This makes it possible to write lightweight
actions—e.g. with shell scripts. A composite action can even
<a href="https://github.blog/changelog/2021-08-25-github-actions-reduce-duplication-with-action-composition/">reference</a> other actions in those steps.</p>
<h3 id=how-we-release>How We Release Actions in Go</h3>
<p>To distribute our actions written in Go, we build static binaries from
the source code and check them into the GitHub repository for the
action.</p>
<h4>Example</h4>
<p>For an action that needs to run on both 64-bit x86 and ARM
machines running Linux or Windows, it would be enough to use six files:</p>
<div class=highlight><pre><span></span><code>$ tree
.
├── action.yml
├── invoke-binary.js
├── main-linux-amd64-e9d351bd367300ec85b9ba777812c42be2570a64
├── main-linux-arm64-e9d351bd367300ec85b9ba777812c42be2570a64
├── main-windows-amd64-e9d351bd367300ec85b9ba777812c42be2570a64
└── main-windows-arm64-e9d351bd367300ec85b9ba777812c42be2570a64
0 directories, 6 files
</code></pre></div>
<p>In order to invoke the <strong>correct</strong> static binary, we use a tiny JavaScript
<a href="/code/invoke-binary.js">shim</a> to determine the current operating system (<code>GOOS</code>) and
platform / architecture (<code>GOARCH</code>). The shim dispatches the correct static
binary as follows:</p>
<div class=highlight><pre><span></span><code><span class=kd>function</span> <span class=nx>chooseBinary</span><span class=p>()</span> <span class=p>{</span>
<span class=c1>// ...</span>
<span class=k>if</span> <span class=p>(</span><span class=nx>platform</span> <span class=o>===</span> <span class=s1>'linux'</span> <span class=o>&&</span> <span class=nx>arch</span> <span class=o>===</span> <span class=s1>'x64'</span><span class=p>)</span> <span class=p>{</span>
<span class=k>return</span> <span class=sb>`main-linux-amd64-</span><span class=si>${</span><span class=nx>VERSION</span><span class=si>}</span><span class=sb>`</span>
<span class=p>}</span>
<span class=c1>// ...</span>
<span class=p>}</span>
<span class=kd>const</span> <span class=nx>binary</span> <span class=o>=</span> <span class=nx>chooseBinary</span><span class=p>()</span>
<span class=kd>const</span> <span class=nx>mainScript</span> <span class=o>=</span> <span class=sb>`</span><span class=si>${</span><span class=nx>__dirname</span><span class=si>}</span><span class=sb>/</span><span class=si>${</span><span class=nx>binary</span><span class=si>}</span><span class=sb>`</span>
<span class=kd>const</span> <span class=nx>spawnSyncReturns</span> <span class=o>=</span> <span class=nx>childProcess</span><span class=p>.</span><span class=nx>spawnSync</span><span class=p>(</span><span class=nx>mainScript</span><span class=p>,</span> <span class=p>{</span> <span class=nx>stdio</span><span class=o>:</span> <span class=s1>'inherit'</span> <span class=p>})</span>
</code></pre></div>
<p>and in the <code>action.yml</code> we just "pretend to be JavaScript" to call out to
our shim:</p>
<div class=highlight><pre><span></span><code><span class=nt>runs</span><span class=p>:</span>
<span class=nt>using</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">node16</span>
<span class=nt>main</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">invoke-binary.js</span>
</code></pre></div>
<h4>Releasing</h4>
<p>At Blend, we maintain all Go actions in our internal Go monorepo. We publish
them into the <code>actions</code> organization within our GitHub Enterprise
instance. When a Go action is updated, a post-merge step builds static binaries
for the subset of architectures we need to support and pushes a commit directly
to the respective <code>actions/${ACTION}</code> repository. For example, changes in the
Go monorepo to code in <code>project/github-actions/{cmd,pkg}/build-docker-image/</code>
will result in a commit to the <code>actions/build-docker-image</code> repository.</p>
<h4>Benefits</h4>
<p>Using this approach, an action written in Go runs <strong>immediately</strong>
in the same way an action written in JavaScript does. We eliminate the
need for <strong>any</strong> Go dependencies on the actions runner: GitHub only grabs our
<code>invoke-binary.js</code> and static binaries. To make the retrieval fast, we go out
of our way to <a href="https://words.filippo.io/shrink-your-go-binaries-with-this-one-weird-trick/">shrink</a> the static binaries and make a special "release"
branch that contains a minimal set of files to run the
action<sup id=sf-how-to-write-github-actions-in-go-4-back><a href=#sf-how-to-write-github-actions-in-go-4 class=simple-footnote title="This means we don't need to include any Go source code (or go.mod, etc.) in our "release" branch. By the same token, we wouldn't want to check in compiled static binaries to our "development" branch.">4</a></sup>.</p>
<p>Our approach of using prebuilt binaries is the same idea in spirit as the
recommended approach for JavaScript actions. For JavaScript actions, it
is recommended to use the <code>ncc</code> <a href="https://github.com/vercel/ncc">compiler</a> to create a single <code>index.js</code>
file. With this <strong>single file</strong> entrypoint, the action just executes
that file without any other setup necessary. Since Go is a compiled language,
there is no direct equivalent of the "I have some source code and an
interpreter" Node.js approach, hence the need for including prebuilt binaries.
Interestingly enough, the <code>ncc</code> project lists the Go compiler as one of its
motivations, so there must be something there!</p>
<h4>Just Go?</h4>
<p>This approach can absolutely be used by programming language ecosystems other
than Go. For example, with the Nuitka <a href="https://nuitka.net/">compiler</a> for Python, standalone
executables can be produced in the same way. For compiled languages like C++ or
Rust, creating prebuilt binaries can be straightforward.</p>
<p>One unique advantage Go has in this arena is the default mode of creating
<a href="https://www.arp242.net/static-go.html">statically linked</a> binaries. This makes it much easier to <strong>just run</strong> on
a new machine without needing<sup id=sf-how-to-write-github-actions-in-go-5-back><a href=#sf-how-to-write-github-actions-in-go-5 class=simple-footnote title="It's worth mentioning: cgo is not Go. Generating a static binary when using cgo is possible but much more challenging. Cross-compiling a static binary is even more challenging.">5</a></sup>
to install or locate dependencies. Additionally, the Go compiler's ability to
<a href="https://www.digitalocean.com/community/tutorials/building-go-applications-for-different-operating-systems-and-architectures">cross-compile</a> binaries from a single development machine is incredibly
useful for the distribution strategy we use here:</p>
<div class=highlight><pre><span></span><code>CGO_ENABLED=0 GOOS=linux GOARCH=arm64 \
go build \
-ldflags="-s -w" \
-o main-linux-arm64-e9d351bd367300ec85b9ba777812c42be2570a64 \
.
</code></pre></div>
<h3 id=how-we-write>How We Write Actions in Go</h3>
<h4>Small Entrypoint Scripts</h4>
<p>As a rule, we try to make <code>cmd/${ACTION}/main.go</code> scripts as short as possible
so we can maximize the amount of code that can be tested<sup id=sf-how-to-write-github-actions-in-go-6-back><a href=#sf-how-to-write-github-actions-in-go-6 class=simple-footnote title="Though it is possible to test code in package main, it is not common. This is particularly challenging for code paths that end with os.Exit().">6</a></sup>:</p>
<div class=highlight><pre><span></span><code><span class=c1>// FILE: cmd/hypothetical/main.go</span>
<span class=kn>package</span> <span class=nx>main</span>
<span class=kn>import</span> <span class=p>(</span>
<span class=s>"context"</span>
<span class=nx>githubactions</span> <span class=s>"github.com/sethvargo/go-githubactions"</span>
<span class=s>"github.com/blend/hypothetical-action/pkg/hypothetical"</span>
<span class=p>)</span>
<span class=kd>func</span> <span class=nx>run</span><span class=p>()</span> <span class=kt>error</span> <span class=p>{</span>
<span class=nx>ctx</span> <span class=o>:=</span> <span class=nx>context</span><span class=p>.</span><span class=nx>Background</span><span class=p>()</span>
<span class=nx>action</span> <span class=o>:=</span> <span class=nx>githubactions</span><span class=p>.</span><span class=nx>New</span><span class=p>()</span>
<span class=nx>cfg</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>NewFromInputs</span><span class=p>(</span><span class=nx>action</span><span class=p>)</span>
<span class=k>if</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
<span class=k>return</span> <span class=nx>err</span>
<span class=p>}</span>
<span class=k>return</span> <span class=nx>hypothetical</span><span class=p>.</span><span class=nx>Run</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=nx>cfg</span><span class=p>)</span>
<span class=p>}</span>
<span class=kd>func</span> <span class=nx>main</span><span class=p>()</span> <span class=p>{</span>
<span class=nx>err</span> <span class=o>:=</span> <span class=nx>run</span><span class=p>()</span>
<span class=k>if</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
<span class=nx>action</span><span class=p>.</span><span class=nx>Fatalf</span><span class=p>(</span><span class=s>"%v"</span><span class=p>,</span> <span class=nx>err</span><span class=p>)</span>
<span class=p>}</span>
<span class=p>}</span>
</code></pre></div>
<h4>Separate Configuration Parsing</h4>
<p>By loading <strong>all</strong> inputs and configuration at the outset, an action
can be much easier to reason about: once parsed, a single configuration
struct can be passed to the code implementing the business logic. For example:</p>
<div class=highlight><pre><span></span><code><span class=c1>// FILE: pkg/hypothetical/config.go</span>
<span class=kd>type</span> <span class=nx>Config</span> <span class=kd>struct</span> <span class=p>{</span>
<span class=nx>Role</span> <span class=kt>string</span>
<span class=nx>LeaseDuration</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Duration</span>
<span class=p>}</span>
<span class=kd>func</span> <span class=nx>NewFromInputs</span><span class=p>(</span><span class=nx>action</span> <span class=o>*</span><span class=nx>githubactions</span><span class=p>.</span><span class=nx>Action</span><span class=p>)</span> <span class=p>(</span><span class=o>*</span><span class=nx>Config</span><span class=p>,</span> <span class=kt>error</span><span class=p>)</span> <span class=p>{</span>
<span class=nx>lease</span> <span class=o>:=</span> <span class=nx>action</span><span class=p>.</span><span class=nx>GetInput</span><span class=p>(</span><span class=s>"lease-duration"</span><span class=p>)</span>
<span class=nx>d</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>time</span><span class=p>.</span><span class=nx>ParseDuration</span><span class=p>(</span><span class=nx>lease</span><span class=p>)</span>
<span class=k>if</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
<span class=k>return</span> <span class=kc>nil</span><span class=p>,</span> <span class=nx>err</span>
<span class=p>}</span>
<span class=nx>c</span> <span class=o>:=</span> <span class=nx>Config</span><span class=p>{</span>
<span class=nx>Role</span><span class=p>:</span> <span class=nx>action</span><span class=p>.</span><span class=nx>GetInput</span><span class=p>(</span><span class=s>"role"</span><span class=p>),</span>
<span class=nx>LeaseDuration</span><span class=p>:</span> <span class=nx>d</span><span class=p>,</span>
<span class=p>}</span>
<span class=k>return</span> <span class=o>&</span><span class=nx>c</span><span class=p>,</span> <span class=kc>nil</span>
<span class=p>}</span>
</code></pre></div>
<h4>No Globals</h4>
<p>The <a href="https://github.com/sethvargo/go-githubactions">sethvargo/go-githubactions</a> project provides an idiomatic
Go package that is roughly equivalent to the <code>@actions/core</code> JavaScript
<a href="https://www.npmjs.com/package/@actions/core">package</a>. We utilize it wherever we can, but try to follow some larger
principles to write testable code.</p>
<p>When writing code that uses the <code>githubactions</code> package, a pointer
<code>action *githubactions.Action</code> should be used rather than the global wrappers
around the package <code>defaultAction</code> <a href="https://github.com/sethvargo/go-githubactions/blob/v0.5.1/actions_root.go#L20">struct</a>. For example:</p>
<div class=highlight><pre><span></span><code><span class=nx>role</span> <span class=o>:=</span> <span class=nx>action</span><span class=p>.</span><span class=nx>GetInput</span><span class=p>(</span><span class=s>"role"</span><span class=p>)</span>
<span class=c1>// // Don't do this:</span>
<span class=c1>// role := githubactions.GetInput("role")</span>
</code></pre></div>
<p>In order to test code involving GitHub Actions, it's critical to be able to
both control environment variables (these are inputs) and to monitor writes to
STDOUT. In order to do this in tests, both the STDOUT writer and the
<code>Getenv()</code> provider can be replaced:</p>
<div class=highlight><pre><span></span><code><span class=kd>func</span> <span class=nx>TestNewFromInputs</span><span class=p>(</span><span class=nx>t</span> <span class=o>*</span><span class=nx>testing</span><span class=p>.</span><span class=nx>T</span><span class=p>)</span> <span class=p>{</span>
<span class=c1>// ...</span>
<span class=nx>actionLog</span> <span class=o>:=</span> <span class=nx>bytes</span><span class=p>.</span><span class=nx>NewBuffer</span><span class=p>(</span><span class=kc>nil</span><span class=p>)</span>
<span class=nx>envMap</span> <span class=o>:=</span> <span class=kd>map</span><span class=p>[</span><span class=kt>string</span><span class=p>]</span><span class=kt>string</span><span class=p>{</span>
<span class=s>"INPUT_ROLE"</span><span class=p>:</span> <span class=s>"user"</span><span class=p>,</span>
<span class=s>"INPUT_LEASE-DURATION"</span><span class=p>:</span> <span class=s>"1h"</span><span class=p>,</span>
<span class=p>}</span>
<span class=nx>getenv</span> <span class=o>:=</span> <span class=kd>func</span><span class=p>(</span><span class=nx>key</span> <span class=kt>string</span><span class=p>)</span> <span class=kt>string</span> <span class=p>{</span>
<span class=k>return</span> <span class=nx>envMap</span><span class=p>[</span><span class=nx>key</span><span class=p>]</span>
<span class=p>}</span>
<span class=nx>action</span> <span class=o>:=</span> <span class=nx>githubactions</span><span class=p>.</span><span class=nx>New</span><span class=p>(</span>
<span class=nx>githubactions</span><span class=p>.</span><span class=nx>WithWriter</span><span class=p>(</span><span class=nx>actionLog</span><span class=p>),</span>
<span class=nx>githubactions</span><span class=p>.</span><span class=nx>WithGetenv</span><span class=p>(</span><span class=nx>getenv</span><span class=p>),</span>
<span class=p>)</span>
<span class=c1>// ...</span>
<span class=nx>it</span><span class=p>.</span><span class=nx>Equal</span><span class=p>(</span><span class=s>"..."</span><span class=p>,</span> <span class=nx>actionLog</span><span class=p>.</span><span class=nx>String</span><span class=p>())</span>
<span class=p>}</span>
</code></pre></div>
<h4>Invoking Actions Locally</h4>
<p>To sanity check an implementation, it can be quite useful to run an
action <strong>locally</strong> instead of doing a pre-release and waiting on a fully
triggered GitHub Actions workflow. To run an action locally, it's enough to run
the Go script with the correct environment variables.</p>
<p>There are two types of environment variables needed. The first type are
<code>GITHUB_*</code> environment variables that come with the
workflow. The other type are inputs that are provided
in <code>inputs:</code> to the action (i.e. the inputs from <code>action.yml</code>), which get
transformed into <code>INPUT_*</code> environment variables by GitHub.</p>
<p>For example<sup id=sf-how-to-write-github-actions-in-go-7-back><a href=#sf-how-to-write-github-actions-in-go-7 class=simple-footnote title="For action inputs in kebab-case, the corresponding environment variable will have a hyphen, e.g. INPUT_LEASE-DURATION. Using environment variable names with a hyphen requires a little bit of extra care in most shells, hence the usage of env INPUT_LEASE-DURATION=.... ">7</a></sup>:</p>
<div class=highlight><pre><span></span><code>env \
'GITHUB_API_URL=https://api.github.com' \
'GITHUB_REPOSITORY=blend/repo-that-uses-an-action' \
'INPUT_ROLE=user' \
'INPUT_LEASE-DURATION=1h' \
go run ./cmd/hypothetical/main.go
</code></pre></div>
<h3 id=why-not-docker>Why Not Docker?</h3>
<p>Using prebuilt static binaries is not the only choice for writing an
action. We explicitly considered using a Docker container action or a
composite action but elected not to use either.</p>
<h4>Using a Docker Action</h4>
<p>The first obvious choice here would be to write a Dockerfile for the Go
code and use a Docker container action. For example, the GitHub Actions
<a href="https://github.com/the-gophers/go-action">tutorial</a> at GopherCon 2021 recommended this approach as do the
<a href="https://github.com/sethvargo/go-githubactions/tree/v0.5.2#publishing">publishing</a> instructions for the <code>githubactions</code> package. However, this
experience is not as smooth as the JavaScript one.</p>
<p>With a Docker container action, the image reference can either be a Dockerfile
or an image in a container registry. Referencing a Dockerfile directly
incurs a large cost: every<sup id=sf-how-to-write-github-actions-in-go-8-back><a href=#sf-how-to-write-github-actions-in-go-8 class=simple-footnote title="It's certainly possible to use actions/cache to reuse a Docker build context across workflow runs, but it is not easy to get right. This puts an unnecessary burden on users of an action. ">8</a></sup> invocation of the action requires the image to be built. Pulling
an image from a public container registry emulates the snappy "run it now"
behavior of JavaScript actions. For images stored in a <strong>private</strong> container
registry, this creates a new challenge. To use an action referencing a private
image, users would need to first authenticate to a registry to pull an image
that they didn't even know they were using:</p>
<div class=highlight><pre><span></span><code><span class=nt>steps</span><span class=p>:</span>
<span class="p p-Indicator">-</span> <span class=nt>name</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">Login to ECR</span>
<span class=nt>uses</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">docker/login-action@v1</span>
<span class=nt>with</span><span class=p>:</span>
<span class=nt>registry</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">${{ env.AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com</span>
<span class=nt>username</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">${{ secrets.AWS_ACCESS_KEY_ID }}</span>
<span class=nt>password</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">${{ secrets.AWS_SECRET_ACCESS_KEY }}</span>
<span class="p p-Indicator">-</span> <span class=nt>name</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">Invoke Hypothetical</span>
<span class=nt>uses</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">blend/hypothetical-action@main</span>
<span class=nt>with</span><span class=p>:</span>
<span class=nt>role</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">user</span>
<span class=nt>lease-duration</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">1h</span>
</code></pre></div>
<p>For internal actions used within an engineering organization
(e.g. within a GitHub Enterprise instance) it's very likely that most images
will be in a private container registry.</p>
<h4>Using a Composite Action</h4>
<p>It is possible to avoid the overhead of Docker build and authentication by
using a composite action. Starting from Go source code<sup id=sf-how-to-write-github-actions-in-go-9-back><a href=#sf-how-to-write-github-actions-in-go-9 class=simple-footnote title='"Starting from Go source code" as opposed to the other approach, i.e. just distributing prebuilt binaries. '>9</a></sup>, the only option is to compile and run that code. This means a
composite action needs to ensure Go is installed on the actions runner. For
example:</p>
<div class=highlight><pre><span></span><code><span class=nt>runs</span><span class=p>:</span>
<span class=nt>using</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">composite</span>
<span class=nt>steps</span><span class=p>:</span>
<span class="p p-Indicator">-</span> <span class=nt>uses</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">actions/setup-go@v2</span>
<span class=nt>with</span><span class=p>:</span>
<span class=nt>go-version</span><span class=p>:</span> <span class=s>'1.17.6'</span>
<span class="p p-Indicator">-</span> <span class=nt>run</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">go run ./main.go</span>
</code></pre></div>
<p>However, this has the same problem as the approach of building a Dockerfile
before running it: the default usage (no caching) involves a significant
cost waiting for build before the action actually runs. What's more,
running <a href="https://github.com/actions/setup-go">actions/setup-go</a> on the actions runner may overwrite an existing
version of Go installed by the workflow job actually invoking this action,
causing invisible breakage in workflows using this action.</p>
<h3 id=conclusion>Conclusion</h3>
<p>Using a tiny JavaScript shim, actions written in Go can be on equal
footing with native JavaScript actions. As we discussed above, there are many
benefits that come from this first-class native support—chiefly speed of
invocation and simplicity of setup. Best of all, this allows us to bring all
the benefits of Go when writing an action. For internal
actions within an engineering organization, this allows us to reuse existing
Go libraries within our actions. With GitHub Actions and Go, we <strong>can</strong>
have our cake and eat it too.</p>
<p><img alt="Go; now with Cake!" src="/images/gopher-cake-art.png"></p><ol class=simple-footnotes><li id=sf-how-to-write-github-actions-in-go-1>It was recent when I wrote this on February 7, 2022. <a href=#sf-how-to-write-github-actions-in-go-1-back class=simple-footnote-back>↩</a></li><li id=sf-how-to-write-github-actions-in-go-2>For example, using <a href="https://github.com/actions/checkout">actions/checkout</a> to checkout code and
<a href="https://github.com/actions/cache">actions/cache</a> to cache dependencies to speed up CI runs. <a href=#sf-how-to-write-github-actions-in-go-2-back class=simple-footnote-back>↩</a></li><li id=sf-how-to-write-github-actions-in-go-3>E.g. for teams that prefer something other than JavaScript. <a href=#sf-how-to-write-github-actions-in-go-3-back class=simple-footnote-back>↩</a></li><li id=sf-how-to-write-github-actions-in-go-4>This means we don't need to include any Go source code (or <code>go.mod</code>,
etc.) in our "release" branch. By the same token, we wouldn't want to check in
compiled static binaries to our "development" branch. <a href=#sf-how-to-write-github-actions-in-go-4-back class=simple-footnote-back>↩</a></li><li id=sf-how-to-write-github-actions-in-go-5>It's worth <a href="https://dave.cheney.net/2016/01/18/cgo-is-not-go">mentioning</a>: cgo is not Go.
Generating a static binary when using cgo is possible but much more
challenging. Cross-compiling a static binary is even more challenging. <a href=#sf-how-to-write-github-actions-in-go-5-back class=simple-footnote-back>↩</a></li><li id=sf-how-to-write-github-actions-in-go-6>Though it is
possible to test code in <code>package main</code>, it is not common. This is particularly
challenging for code paths that end with <code>os.Exit()</code>. <a href=#sf-how-to-write-github-actions-in-go-6-back class=simple-footnote-back>↩</a></li><li id=sf-how-to-write-github-actions-in-go-7>For action inputs in <code>kebab-case</code>, the corresponding
environment variable will have a hyphen, e.g. <code>INPUT_LEASE-DURATION</code>. Using
environment variable names with a hyphen requires a little bit of extra care
in most shells, hence the usage of <code>env INPUT_LEASE-DURATION=...</code>. <a href=#sf-how-to-write-github-actions-in-go-7-back class=simple-footnote-back>↩</a></li><li id=sf-how-to-write-github-actions-in-go-8>It's certainly possible to <a href="https://docs.github.com/en/actions/advanced-guides/caching-dependencies-to-speed-up-workflows">use</a>
<a href="https://github.com/actions/cache">actions/cache</a> to reuse a Docker build context across workflow runs, but
it is not easy to get right. This puts an unnecessary burden on users of an
action. <a href=#sf-how-to-write-github-actions-in-go-8-back class=simple-footnote-back>↩</a></li><li id=sf-how-to-write-github-actions-in-go-9>"Starting from Go
source code" as opposed to the other approach, i.e. just distributing prebuilt
binaries. <a href=#sf-how-to-write-github-actions-in-go-9-back class=simple-footnote-back>↩</a></li></ol>Bare Metal Kubernetes with Tailscale2021-12-14T00:00:00-08:002021-12-14T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-12-14:/2021/12/tailsk8s.html<p>For my most recent side project <code>tailsk8s</code>, I've been <a href="https://github.com/dhermes/tailsk8s/tree/v1.20211214.1">hacking</a> on a
bare metal Kubernetes cluster that uses <a href="https://tailscale.com/">Tailscale</a> for networking.
I had a lot of fun and learned a lot, but the TL;DR is that each Kubernetes
node is a Tailscale <a href="https://tailscale.com/kb/1019/subnets/">subnet router</a> and uses the <code>kubenet</code> <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#kubenet">CNI …</a></p><p>For my most recent side project <code>tailsk8s</code>, I've been <a href="https://github.com/dhermes/tailsk8s/tree/v1.20211214.1">hacking</a> on a
bare metal Kubernetes cluster that uses <a href="https://tailscale.com/">Tailscale</a> for networking.
I had a lot of fun and learned a lot, but the TL;DR is that each Kubernetes
node is a Tailscale <a href="https://tailscale.com/kb/1019/subnets/">subnet router</a> and uses the <code>kubenet</code> <a href="https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#kubenet">CNI</a> to
indicate the relevant subnet to the rest of the cluster.</p>
<p>To demonstrate the process of bringing up the cluster and to see the
networking in action I recorded two videos. The first one involves only
the four<sup id=sf-tailsk8s-1-back><a href=#sf-tailsk8s-1 class=simple-footnote title="The four node cluster also has two control plane nodes because I don't have enough machines. Luckily I don't mind if they can't form a quorum.">1</a></sup> bare metal nodes that I literally have in my house. The second
video turns it into a hybrid cluster by adding an AWS EC2 VM and a GCP GCE
instance.</p>
<h3>Bare Metal</h3>
<iframe width=560 height=315 src="https://www.youtube.com/embed/ws3mlpRUc8E" title="YouTube video player" frameborder=0 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<h3>Adding Public Cloud VMs</h3>
<iframe width=560 height=315 src="https://www.youtube.com/embed/6oSY0CP9o7o" title="YouTube video player" frameborder=0 allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe><ol class=simple-footnotes><li id=sf-tailsk8s-1>The four node cluster also has two control plane nodes because
I don't have enough machines. Luckily I don't mind if they can't form a
quorum. <a href=#sf-tailsk8s-1-back class=simple-footnote-back>↩</a></li></ol>Remodeling the House While Living in It2021-11-01T00:00:00-07:002021-11-01T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-11-01:/2021/11/safe-column-renames.html<div style="text-align: center;">
<p><img alt="Rename Name Tag" src="/images/rename_created_at.jpg"></p>
</div>
<h3>Minor Mismatch</h3>
<p>When using a database in an application, there are many ways the idioms from
the database ecosystem can disagree with the idioms in the programming language
used to write the application. The object-relational impedance <a href="https://en.wikipedia.org/wiki/Object%E2%80%93relational_impedance_mismatch">mismatch</a> is
one such example of this, but that is mostly about differences between …</p><div style="text-align: center;">
<p><img alt="Rename Name Tag" src="/images/rename_created_at.jpg"></p>
</div>
<h3>Minor Mismatch</h3>
<p>When using a database in an application, there are many ways the idioms from
the database ecosystem can disagree with the idioms in the programming language
used to write the application. The object-relational impedance <a href="https://en.wikipedia.org/wiki/Object%E2%80%93relational_impedance_mismatch">mismatch</a> is
one such example of this, but that is mostly about differences between
relational objects (i.e. rows in tables) and programming language type
systems.</p>
<p>Sometimes, the differences are just cosmetic. But this can still cause
issues with developer ergonomics, opportunities for subtle bugs or even lint
violations for codebases on the stricter side. Here I want to highlight the
specific issue when PostgreSQL column naming conventions disagree with field
naming conventions in JavaScript / TypeScript types.</p>
<h3>I Made a Mess</h3>
<p>Consider the following TypeScript type for tracking issues in a ticketing
system:</p>
<div class=highlight><pre><span></span><code><span class=k>import</span> <span class=o>*</span> <span class=kr>as</span> <span class=nx>typeorm</span> <span class=k>from</span> <span class=s1>'typeorm'</span><span class=p>;</span>
<span class=kd>@typeorm</span><span class=p>.</span><span class=nx>Entity</span><span class=p>()</span>
<span class=k>export</span> <span class=kd>class</span> <span class=nx>Ticket</span> <span class=p>{</span>
<span class=kd>@typeorm</span><span class=p>.</span><span class=nx>PrimaryColumn</span><span class=p>({</span> <span class=kd>type</span><span class=o>:</span> <span class=s1>'uuid'</span> <span class=p>})</span>
<span class=nx>id</span><span class=o>!:</span> <span class=kt>number</span><span class=p>;</span>
<span class=kd>@typeorm</span><span class=p>.</span><span class=nx>Column</span><span class=p>()</span>
<span class=nx>owner</span><span class=o>!:</span> <span class=kt>string</span><span class=p>;</span>
<span class=kd>@typeorm</span><span class=p>.</span><span class=nx>Column</span><span class=p>()</span>
<span class=nx>description</span><span class=o>!:</span> <span class=kt>string</span><span class=p>;</span>
<span class=kd>@typeorm</span><span class=p>.</span><span class=nx>CreateDateColumn</span><span class=p>({</span> <span class=kd>type</span><span class=o>:</span> <span class=s1>'timestamp with time zone'</span> <span class=p>})</span>
<span class=nx>createdAt</span><span class=o>!:</span> <span class=nb>Date</span><span class=p>;</span>
<span class=kd>@typeorm</span><span class=p>.</span><span class=nx>UpdateDateColumn</span><span class=p>({</span> <span class=kd>type</span><span class=o>:</span> <span class=s1>'timestamp with time zone'</span> <span class=p>})</span>
<span class=nx>updatedAt</span><span class=o>!:</span> <span class=nb>Date</span><span class=p>;</span>
<span class=kd>@typeorm</span><span class=p>.</span><span class=nx>Column</span><span class=p>({</span> <span class=kd>type</span><span class=o>:</span> <span class=s1>'timestamp with time zone'</span><span class=p>,</span> <span class=nx>nullable</span>: <span class=kt>true</span> <span class=p>})</span>
<span class=nx>resolvedAt?</span>: <span class=kt>Date</span><span class=p>;</span>
<span class=p>}</span>
</code></pre></div>
<!--
CREATE TABLE "ticket" (
"id" uuid NOT NULL,
"owner" character varying NOT NULL,
"description" character varying NOT NULL,
"createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
"updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
"resolvedAt" TIMESTAMP WITH TIME ZONE,
CONSTRAINT "PK_d9a0835407701eb86f874474b7c" PRIMARY KEY ("id")
);
CREATE INDEX
"IDX_4fd0fa28cf982e5252b358caa9"
ON
"ticket" ("owner", "updatedAt");
INSERT INTO
ticket (id, "owner", "description", "createdAt", "updatedAt", "resolvedAt")
VALUES
('9ca76412-6248-4928-bbf8-e4c32ccec193', 'bob@mail.invalid', 'Deprecate GET-form of DELETE', '2021-10-22 13:31:48.467759+00', '2021-10-26 01:50:11.762684+00', NULL),
('3076d8bc-81b9-4f8e-af44-0b62493e1ff6', 'bev@mail.invalid', 'Implement protobuf parsing', '2021-10-23 18:41:59.909022+00', '2021-10-23 18:41:59.909022+00', NULL),
('2a7eacd6-f758-4f9b-ab26-1c47cb2c009a', 'barb@mail.invalid', 'Compare DB purge strategies', '2021-10-23 12:13:07.682559+00', '2021-10-27 07:45:13.110361+00', '2021-10-27 07:45:13.110361+00'),
('80c47584-0716-4952-8937-dd6af18d516b', 'bob@mail.invalid', 'Explicitly require API version', '2021-10-25 19:22:13.919551+00', '2021-10-25 19:22:13.919551+00', NULL);
-->
<p>Using TypeORM with the defaults, a developer would end with a table of the
form:</p>
<div class=highlight><pre><span></span><code><span class=n>tracker</span><span class=o>=></span> \<span class=n>d</span> <span class=n>ticket</span>
<span class=n>Table</span> <span class=s2>"tracker.ticket"</span>
<span class=n>Column</span> <span class=o>|</span> <span class=n>Type</span> <span class=o>|</span> <span class=n>Collation</span> <span class=o>|</span> <span class=n>Nullable</span> <span class=o>|</span> <span class=n>Default</span>
<span class=o>-------------+--------------------------+-----------+----------+---------</span>
<span class=n>id</span> <span class=o>|</span> <span class=n>uuid</span> <span class=o>|</span> <span class=o>|</span> <span class=ow>not</span> <span class="nb nb-Type">null</span> <span class=o>|</span>
<span class=n>owner</span> <span class=o>|</span> <span class=n>character</span> <span class=n>varying</span> <span class=o>|</span> <span class=o>|</span> <span class=ow>not</span> <span class="nb nb-Type">null</span> <span class=o>|</span>
<span class=n>description</span> <span class=o>|</span> <span class=n>character</span> <span class=n>varying</span> <span class=o>|</span> <span class=o>|</span> <span class=ow>not</span> <span class="nb nb-Type">null</span> <span class=o>|</span>
<span class=n>createdAt</span> <span class=o>|</span> <span class=n>timestamp</span> <span class=n>with</span> <span class=n>time</span> <span class=n>zone</span> <span class=o>|</span> <span class=o>|</span> <span class=ow>not</span> <span class="nb nb-Type">null</span> <span class=o>|</span> <span class=n>now</span><span class=p>()</span>
<span class=n>updatedAt</span> <span class=o>|</span> <span class=n>timestamp</span> <span class=n>with</span> <span class=n>time</span> <span class=n>zone</span> <span class=o>|</span> <span class=o>|</span> <span class=ow>not</span> <span class="nb nb-Type">null</span> <span class=o>|</span> <span class=n>now</span><span class=p>()</span>
<span class=n>resolvedAt</span> <span class=o>|</span> <span class=n>timestamp</span> <span class=n>with</span> <span class=n>time</span> <span class=n>zone</span> <span class=o>|</span> <span class=o>|</span> <span class=o>|</span>
<span class=n>Indexes</span><span class=p>:</span>
<span class=s2>"PK_d9a0835407701eb86f874474b7c"</span> <span class=n>PRIMARY</span> <span class=n>KEY</span><span class=p>,</span> <span class=n>btree</span> <span class=p>(</span><span class=n>id</span><span class=p>)</span>
<span class=s2>"IDX_4fd0fa28cf982e5252b358caa9"</span> <span class=n>btree</span> <span class=p>(</span><span class=n>owner</span><span class=p>,</span> <span class=s2>"updatedAt"</span><span class=p>)</span>
</code></pre></div>
<p>Note the idiomatic JavaScript field names (<code>camelCase</code>) being directly ported
as column names. This causes problems when using them naively in PostgreSQL:</p>
<div class=highlight><pre><span></span><code><span class=gp>tracker=></span> <span class=k>SELECT</span> <span class=k>owner</span><span class=p>,</span> <span class=n>description</span><span class=p>,</span> <span class=n>createdAt</span> <span class=k>FROM</span> <span class=n>ticket</span> <span class=k>WHERE</span> <span class=n>createdAt</span> <span class=o>=</span> <span class=n>updatedAt</span><span class=p>;</span>
<span class=gs>ERROR:</span><span class=gr> column "createdat" does not exist</span>
<span class=gs>LINE 1:</span><span class=gr> SELECT owner, description, createdAt FROM ticket WHERE creat...</span>
<span class=gr> ^</span>
<span class=gs>HINT:</span><span class=gr> Perhaps you meant to reference the column "ticket.createdAt".</span>
</code></pre></div>
<p>A somewhat reasonable response to this may be "but TypeORM writes all my
queries". However, poking around in the database console (<code>psql</code> here)
<strong>should</strong> happen all the time, both during development and when evaluating
migrations, feature usage and performing other other one-off tasks. In order
to actually use the console, the columns need to be quoted to preserve the
casing:</p>
<div class=highlight><pre><span></span><code><span class=gp>tracker=></span> <span class=k>SELECT</span> <span class=k>owner</span><span class=p>,</span> <span class=n>description</span><span class=p>,</span> <span class="s s-Name">"createdAt"</span> <span class=k>FROM</span> <span class=n>ticket</span> <span class=k>WHERE</span> <span class="s s-Name">"createdAt"</span> <span class=o>=</span> <span class="s s-Name">"updatedAt"</span><span class=p>;</span>
<span class=go> owner | description | createdAt</span>
<span class=go>------------------+--------------------------------+-------------------------------</span>
<span class=go> bev@mail.invalid | Implement protobuf parsing | 2021-10-23 18:41:59.909022+00</span>
<span class=go> bob@mail.invalid | Explicitly require API version | 2021-10-25 19:22:13.919551+00</span>
<span class=go>(2 rows)</span>
</code></pre></div>
<p>This is not great. Due to PostgreSQL <a href="https://www.postgresql.org/docs/14/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">handling</a> of identifiers, having
column names be all lowercase is the common convention. In order to
differentiate word boundaries, <code>snake_case</code> is a natural choice. For example
here we'd use <code>created_at</code> instead of <code>createdAt</code>.</p>
<h3>How Do I Get out of the Mess?</h3>
<p>In TypeORM, a column rename is as simple as</p>
<div class=highlight><pre><span></span><code> <span class=kd>@typeorm</span><span class=p>.</span><span class=nx>CreateDateColumn</span><span class=p>({</span> <span class=kd>type</span><span class=o>:</span> <span class=s1>'timestamp with time zone'</span><span class=p>,</span> <span class=nx>name</span><span class=o>:</span> <span class=s1>'created_at'</span> <span class=p>})</span>
<span class=nx>createdAt</span><span class=o>!:</span> <span class=nb>Date</span><span class=p>;</span>
</code></pre></div>
<p>so we can just commit this and run the auto-generated migration? Right?
RIGHT? Maybe. But probably not. The generated migration is harmless enough:</p>
<div class=highlight><pre><span></span><code><span class=k>await</span> <span class=nx>queryRunner</span><span class=p>.</span><span class=nx>query</span><span class=p>(</span><span class=sb>`ALTER TABLE "ticket" RENAME COLUMN "createdAt" TO "created_at"`</span><span class=p>);</span>
</code></pre></div>
<p>However, there is almost always a need for migrations to be compatible with
both the "old code" and the "new code". The most common reason for this is to
enable fast rollbacks if the new code contains a defect. However, it's also
common for applications to be deployed with <strong>rolling updates</strong> or with
<strong>blue green deploys</strong>. In either case, the "old code" and the "new code" can
both be running at literally the same time. So whether it's rollback safety or
deployment strategy, it's easy to construct a strong argument that database
migrations can be applied with the currently running version of the code.</p>
<p>How does this come into play here? Renaming to <code>created_at</code> means that any
query in the currently running version of the code that references <code>createdAt</code>
would just break. At this point, we might just throw up our hands and regret
the fact that our columns have <code>camelCase</code> names. However,
<a href="https://julien.danjou.info/why-you-should-care-that-your-sql-ddl-is-transactional/">transactional DDL</a> and PostgreSQL <a href="https://www.postgresql.org/docs/14/sql-createview.html">views</a> can save us here!</p>
<h3>The First Migration</h3>
<p>We can create a view that <strong>pretends</strong> to be the <code>ticket</code> table while
maintaining the presented column names. Simultaneously, the underlying table
can rename the columns. (In order to make a view named <code>ticket</code>, we first
need to rename the table.) Doing any of these changes <strong>alone</strong> would represent
a broken state for the database, however PostgreSQL allows us to wrap all of
these DDL operations into a transaction!</p>
<p>The aforementioned changes require five statements:</p>
<div class=highlight><pre><span></span><code><span class=c1>-- Start a transaction</span>
<span class=k>BEGIN</span><span class=p>;</span>
<span class=c1>-- Rename all the COLUMNs using `camelCase`</span>
<span class=k>ALTER</span> <span class=k>TABLE</span>
<span class=n>ticket</span>
<span class=k>RENAME</span> <span class=k>COLUMN</span>
<span class=ss>"createdAt"</span> <span class=k>TO</span> <span class=n>created_at</span><span class=p>;</span>
<span class=k>ALTER</span> <span class=k>TABLE</span>
<span class=n>ticket</span>
<span class=k>RENAME</span> <span class=k>COLUMN</span>
<span class=ss>"updatedAt"</span> <span class=k>TO</span> <span class=n>updated_at</span><span class=p>;</span>
<span class=k>ALTER</span> <span class=k>TABLE</span>
<span class=n>ticket</span>
<span class=k>RENAME</span> <span class=k>COLUMN</span>
<span class=ss>"resolvedAt"</span> <span class=k>TO</span> <span class=n>resolved_at</span><span class=p>;</span>
<span class=c1>-- Rename the TABLE so that the VIEW can take its name</span>
<span class=k>ALTER</span> <span class=k>TABLE</span>
<span class=n>ticket</span>
<span class=k>RENAME</span> <span class=k>TO</span>
<span class=n>ticket_actual</span><span class=p>;</span>
<span class=c1>-- Create a VIEW to present the newly renamed column names, but also</span>
<span class=c1>-- present the new names</span>
<span class=k>CREATE</span> <span class=k>VIEW</span>
<span class=n>ticket</span> <span class=k>AS</span>
<span class=k>SELECT</span>
<span class=n>id</span><span class=p>,</span>
<span class=ss>"owner"</span><span class=p>,</span>
<span class=ss>"description"</span><span class=p>,</span>
<span class=n>created_at</span> <span class=k>AS</span> <span class=ss>"createdAt"</span><span class=p>,</span>
<span class=n>updated_at</span> <span class=k>AS</span> <span class=ss>"updatedAt"</span><span class=p>,</span>
<span class=n>resolved_at</span> <span class=k>AS</span> <span class=ss>"resolvedAt"</span><span class=p>,</span>
<span class=n>created_at</span><span class=p>,</span>
<span class=n>updated_at</span><span class=p>,</span>
<span class=n>resolved_at</span>
<span class=k>FROM</span>
<span class=n>ticket_actual</span><span class=p>;</span>
<span class=c1>-- Commit the transaction</span>
<span class=k>COMMIT</span><span class=p>;</span>
</code></pre></div>
<p>To sanity check, notice that even after changing <code>ticket</code> to a view, reads
and writes continue to work:</p>
<div class=highlight><pre><span></span><code><span class=gp>tracker=></span> <span class=kp>\d+</span> <span class=ss>ticket</span>
<span class=go> View "tracker.ticket"</span>
<span class=go> Column | Type | Collation | Nullable | Default | Storage | Description</span>
<span class=go>-------------+-----------------------------+-----------+----------+---------+----------+-------------</span>
<span class=go> id | uuid | | | | plain |</span>
<span class=go>...</span>
<span class=go>View definition:</span>
<span class=go> SELECT ticket_actual.id,</span>
<span class=go> ticket_actual.owner,</span>
<span class=go>...</span>
<span class=go> FROM ticket_actual;</span>
<span class=gp>tracker=></span> <span class=k>INSERT</span> <span class=k>INTO</span>
<span class=gp>tracker-></span> <span class=n>ticket</span> <span class=p>(</span><span class=n>id</span><span class=p>,</span> <span class="s s-Name">"owner"</span><span class=p>,</span> <span class="s s-Name">"description"</span><span class=p>,</span> <span class="s s-Name">"createdAt"</span><span class=p>,</span> <span class="s s-Name">"updatedAt"</span><span class=p>)</span>
<span class=gp>tracker-></span> <span class=k>VALUES</span>
<span class=gp>tracker-></span> <span class=p>(</span>
<span class=gp>tracker(></span> <span class=s1>'9ce77e1f-1390-4a9e-8142-dd5eb257b554'</span><span class=p>,</span>
<span class=gp>tracker(></span> <span class=s1>'bev@mail.invalid'</span><span class=p>,</span>
<span class=gp>tracker(></span> <span class=s1>'Vendor in 3rd party protobuf schema'</span><span class=p>,</span>
<span class=gp>tracker(></span> <span class=s1>'2021-10-24 12:14:15.000173+00'</span><span class=p>,</span>
<span class=gp>tracker(></span> <span class=s1>'2021-10-24 06:37:11.130880+00'</span>
<span class=gp>tracker(></span> <span class=p>);</span>
<span class=go>INSERT 0 1</span>
<span class=gp>tracker=></span> <span class=k>SELECT</span> <span class="s s-Name">"owner"</span><span class=p>,</span> <span class="s s-Name">"description"</span><span class=p>,</span> <span class="s s-Name">"createdAt"</span> <span class=k>FROM</span> <span class=n>ticket</span><span class=p>;</span>
<span class=go> owner | description | createdAt</span>
<span class=go>-------------------+-------------------------------------+-------------------------------</span>
<span class=go> bob@mail.invalid | Deprecate GET-form of DELETE | 2021-10-22 13:31:48.467759+00</span>
<span class=go> bev@mail.invalid | Implement protobuf parsing | 2021-10-23 18:41:59.909022+00</span>
<span class=go> barb@mail.invalid | Compare DB purge strategies | 2021-10-23 12:13:07.682559+00</span>
<span class=go> bob@mail.invalid | Explicitly require API version | 2021-10-25 19:22:13.919551+00</span>
<span class=go> bev@mail.invalid | Vendor in 3rd party protobuf schema | 2021-10-24 12:14:15.000173+00</span>
<span class=go>(5 rows)</span>
</code></pre></div>
<p>This migration can be coupled with a <strong>code change</strong> that starts to use the
newly introduced columns in the view: <code>created_at</code>, <code>updated_at</code> and
<code>resolved_at</code>. During the next deployment (when migrations also run), the
"old code" will use the old column names (which are now aliases in the view)
and the "new code" will use the new column names. Due to the way we've
structured the view, these are both compatible.
The <code>VIEW</code> and <code>TABLE</code> should be interchangeable to application
code<sup id=sf-safe-column-renames-1-back><a href=#sf-safe-column-renames-1 class=simple-footnote title="Unless the code uses SELECT *, which may cause breakage due to three new alias columns in the VIEW.">1</a></sup>.</p>
<h3>The Second Migration</h3>
<p>Once the previous deploy has stabilized (i.e. we know it won't be rolled back)
we know the old column names <code>createdAt</code>, <code>updatedAt</code> and <code>resolvedAt</code> no
longer need to be kept around. As a result, we can remove the view and
restore the table back with its original name:</p>
<div class=highlight><pre><span></span><code><span class=c1>-- Start a transaction</span>
<span class=k>BEGIN</span><span class=p>;</span>
<span class=c1>-- Remove the VIEW</span>
<span class=k>DROP</span> <span class=k>VIEW</span> <span class=n>ticket</span><span class=p>;</span>
<span class=c1>-- Restore the TABLE to the original name</span>
<span class=k>ALTER</span> <span class=k>TABLE</span>
<span class=n>ticket_actual</span>
<span class=k>RENAME</span> <span class=k>TO</span>
<span class=n>ticket</span><span class=p>;</span>
<span class=c1>-- Commit the transaction</span>
<span class=k>COMMIT</span><span class=p>;</span>
</code></pre></div>
<p>All things being equal, application queries going through a <code>TABLE</code> instead
of a <code>VIEW</code> should be preferred. If a <code>VIEW</code> <strong>can</strong> be removed, it
should be as soon as possible. Relying on a <code>VIEW</code> in a codebase over a longer
time span can lead to inefficient queries caused by a mismatch between
developer assumptions about the exposed columns and the actual columns being
transformed in the view. The more complex the view is, the more likely this is
to be true.</p>
<h3>Conclusion</h3>
<p>Transactional DDL allows to do things that would otherwise be impossible
to do without downtime. Combining this with PostgreSQL helpers for
separating storage from presentation, it's possible to make cosmetic renames
to tables and columns safely. It's <strong>always</strong> crucial to ensure migrations
can safely interact with the versions of the codebase immediately before and
after the migration is intended to run. The above approach shows a generic
approach that allows for surfacing "before and after" column views at the
same time. Relying on tools like TypeORM can provide a <strong>lot</strong> of value, but
they can also cause problems if automated outputs like migrations aren't
inspected closely.</p>
<hr style="margin-bottom: 25px; width: 50%;"><ol class=simple-footnotes><li id=sf-safe-column-renames-1>Unless the code uses <code>SELECT *</code>, which may cause breakage due
to three new alias columns in the <code>VIEW</code>. <a href=#sf-safe-column-renames-1-back class=simple-footnote-back>↩</a></li></ol>What Is a Milestone Migration and Why Do I Care?2021-10-30T00:00:00-07:002021-10-30T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-10-30:/2021/10/database-migrations-milestone.html<p><img alt="Database Milestone" src="/images/database_milestone.jpg"></p>
<h3 id=motivation>Motivation</h3>
<p>Over time an application becomes a living thing. When operating a running
service, it's crucial to not only ask the question</p>
<blockquote>
<p>Does the code being deployed work?</p>
</blockquote>
<p>it's also crucial to ask</p>
<blockquote>
<p>Can I safely deploy this change given the currently running version of my
service?</p>
</blockquote>
<p>This second question …</p><p><img alt="Database Milestone" src="/images/database_milestone.jpg"></p>
<h3 id=motivation>Motivation</h3>
<p>Over time an application becomes a living thing. When operating a running
service, it's crucial to not only ask the question</p>
<blockquote>
<p>Does the code being deployed work?</p>
</blockquote>
<p>it's also crucial to ask</p>
<blockquote>
<p>Can I safely deploy this change given the currently running version of my
service?</p>
</blockquote>
<p>This second question is even more crucial in deployment environments where
<strong>rolling update</strong> deploys ensure the "old code" and the "new code" will need
to safely run side-by-side during every deploy.</p>
<p>Running database migrations is a <strong>large</strong> part of this equation. For example,
dropping a database column because the "new code" doesn't rely on it is not
safe because "old code" still relies on it. In simple situations like that,
it's crucial for operators to split the change into multiple stages:</p>
<ul>
<li>Remove <strong>code</strong> that references the column</li>
<li>Deploy that code and ensure the deployed version is stable<sup id=sf-database-migrations-milestone-1-back><a href=#sf-database-migrations-milestone-1 class=simple-footnote title="What do we mean by letting a deployment stabilize? Two things primarily: (1) the rolling update has completed so that the old code isn't running and (2) some form of acceptance testing to ensure the application doesn't need to rollback to a previous version">1</a></sup></li>
<li>Add a migration to drop the column</li>
<li>Run the migration and deploy the code again</li>
</ul>
<h3 id=making-safe>Making Migrations Safe for Rolling Updates</h3>
<p>With the motivation above, it's clear that <strong>some</strong> migrations just cannot be
run if it has been an extended period of time since the application was last
deployed. In order to provide some color, let's walk through a concrete use
case that must be done carefully to be safe in a rolling update deploy
environment.</p>
<p>We have a users table and want to add a <strong>required</strong> (i.e. <code>NOT NULL</code>) column
<code>display_name</code>:</p>
<div class=highlight><pre><span></span><code><span class=gp>golembic=></span> <span class=kp>\d</span> <span class=ss>users</span>
<span class=go> Table "public.users"</span>
<span class=go> Column | Type | Collation | Nullable | Default</span>
<span class=go>------------+------------------------+-----------+----------+---------</span>
<span class=go> id | integer | | not null |</span>
<span class=go> email | character varying(40) | | |</span>
<span class=go> first_name | character varying(40) | | not null |</span>
<span class=go> last_name | character varying(40) | | not null |</span>
<span class=go> city | character varying(100) | | |</span>
<span class=go>Indexes:</span>
<span class=go> "users_pkey" PRIMARY KEY, btree (id)</span>
<span class=go> "uq_users_email" UNIQUE, btree (email)</span>
</code></pre></div>
<p>If we just add the column</p>
<div class=highlight><pre><span></span><code><span class=k>ALTER</span> <span class=k>TABLE</span>
<span class=n>users</span>
<span class=k>ADD</span> <span class=k>COLUMN</span>
<span class=n>display_name</span> <span class=nb>TEXT</span> <span class=k>NOT</span> <span class=k>NULL</span><span class=p>;</span>
</code></pre></div>
<p>then the currently running code will fail on any inserts (since by definition
the code can't be inserting a <code>display_name</code> it never heard of):</p>
<div class=highlight><pre><span></span><code><span class=gp>golembic=></span> <span class=k>INSERT</span> <span class=k>INTO</span>
<span class=gp>golembic-></span> <span class=n>users</span> <span class=p>(</span><span class=n>id</span><span class=p>,</span> <span class=n>email</span><span class=p>,</span> <span class=n>first_name</span><span class=p>,</span> <span class=n>last_name</span><span class=p>)</span>
<span class=gp>golembic-></span> <span class=k>VALUES</span>
<span class=gp>golembic-></span> <span class=p>(</span><span class=mf>702188</span><span class=p>,</span> <span class=s1>'dhermes@mail.invalid'</span><span class=p>,</span> <span class=s1>'Danny'</span><span class=p>,</span> <span class=s1>'Hermes'</span><span class=p>);</span>
<span class=gs>ERROR:</span><span class=gr> null value in column "display_name" of relation "users" violates not-null constraint</span>
<span class=gs>DETAIL:</span><span class=gr> Failing row contains (702188, dhermes@mail.invalid, Danny, Hermes, null, null).</span>
</code></pre></div>
<p>So we need to take a different approach. One way to add a <strong>required</strong> column
in a way that is safe for rolling updates would be to split it into two
migrations:</p>
<div class=highlight><pre><span></span><code><span class=c1>--- 986b93c5e494: Add the column, but allow it to be optional</span>
<span class=k>ALTER</span> <span class=k>TABLE</span>
<span class=n>users</span>
<span class=k>ADD</span> <span class=k>COLUMN</span>
<span class=n>display_name</span> <span class=nb>TEXT</span><span class=p>;</span>
<span class=c1>--- f37715e564e5: Backfill data into the column, then make the column required</span>
<span class=k>UPDATE</span>
<span class=n>users</span>
<span class=k>SET</span>
<span class=n>display_name</span> <span class=o>=</span> <span class=n>first_name</span> <span class=o>||</span> <span class=s1>' '</span> <span class=o>||</span> <span class=n>last_name</span>
<span class=k>WHERE</span>
<span class=n>display_name</span> <span class=k>IS</span> <span class=k>NULL</span><span class=p>;</span>
<span class=k>ALTER</span> <span class=k>TABLE</span>
<span class=n>users</span>
<span class=k>ALTER</span> <span class=k>COLUMN</span>
<span class=n>display_name</span>
<span class=k>SET</span>
<span class=k>NOT</span> <span class=k>NULL</span><span class=p>;</span>
</code></pre></div>
<p>The application code can be updated to also write to the (optional)
<code>display_name</code> column and can be safely re-deployed after <code>986b93c5e494</code> runs.
Once that deploy has stabilized, the application code can be updated to
start to <strong>read</strong> and depend on the (required) <code>display_name</code> column and
can be safely re-deployed after <code>f37715e564e5</code> runs.</p>
<p>We call <code>986b93c5e494</code> a <strong>milestone</strong> migration because it is a special
inflection point in the revision history of the application. The migration
and the associated code must be deployed and stable <strong>before</strong> the next
migration (<code>f37715e564e5</code>) can run. In general, if multiple migrations are
introduced between two deploys, it's safe to apply all of them. However,
a <strong>milestone</strong> can only be run if it's the <strong>last</strong> migration being applied
in a sequence.</p>
<h3 id=caveat>Caveat</h3>
<p>A milestone migration is in some sense a compromise. It mixes <strong>purely</strong>
database specific changes (migrations) with a proxy for the application
version. The proxy (is this milestone migration present in the codebase?)
gives an idication of where in the revision history the <strong>application version</strong>
is.</p>
<h3 id=migration-tooling>Milestone Migration Tooling</h3>
<p>The <code>golembic</code> <a href="https://github.com/dhermes/golembic/tree/2021.10.29">library</a> directly provides support for marking a migration
as a milestone. Continuing with the <code>golembic</code> examples, we can commit
two separate changes to encode the migrations above:</p>
<h4 id=optional-column>Optional Column: <code>986b93c5e494</code></h4>
<p>The first migration can specified as a milestone <a href="https://github.com/dhermes/golembic/blob/2021.10.29/examples/migrations.go#L69">in</a>
<code>examples/migrations.go</code>:</p>
<div class=highlight><pre><span></span><code><span class=p>[]</span><span class=nx>golembic</span><span class=p>.</span><span class=nx>MigrationOption</span><span class=p>{</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptPrevious</span><span class=p>(</span><span class=s>"432f690fcbda"</span><span class=p>),</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptRevision</span><span class=p>(</span><span class=s>"986b93c5e494"</span><span class=p>),</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptMilestone</span><span class=p>(</span><span class=kc>true</span><span class=p>),</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptDescription</span><span class=p>(</span><span class=s>"Add optional `users.display_name` column"</span><span class=p>),</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptUpFromSQL</span><span class=p>(</span><span class=s>"ALTER TABLE users ADD COLUMN display_name TEXT"</span><span class=p>),</span>
<span class=p>},</span>
</code></pre></div>
<h4 id=backfill-column>Backfill and Require Column: <code>f37715e564e5</code></h4>
<p>Since the second migration requires (transactionally) running two migrations,
we introduce a function:</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=p>(</span>
<span class=nx>backfillUsersDisplayName</span> <span class=p>=</span> <span class=s>`</span>
<span class=s>UPDATE</span>
<span class=s> users</span>
<span class=s>SET</span>
<span class=s> display_name = first_name || ' ' || last_name</span>
<span class=s>WHERE</span>
<span class=s> display_name IS NULL</span>
<span class=s>`</span>
<span class=nx>requireUsersDisplayName</span> <span class=p>=</span> <span class=s>`</span>
<span class=s>ALTER TABLE</span>
<span class=s> users</span>
<span class=s>ALTER COLUMN</span>
<span class=s> display_name</span>
<span class=s>SET</span>
<span class=s> NOT NULL</span>
<span class=s>`</span>
<span class=p>)</span>
<span class=kd>func</span> <span class=nx>RequiredDisplayName</span><span class=p>(</span><span class=nx>ctx</span> <span class=nx>context</span><span class=p>.</span><span class=nx>Context</span><span class=p>,</span> <span class=nx>tx</span> <span class=o>*</span><span class=nx>sql</span><span class=p>.</span><span class=nx>Tx</span><span class=p>)</span> <span class=kt>error</span> <span class=p>{</span>
<span class=nx>_</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>tx</span><span class=p>.</span><span class=nx>ExecContext</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=nx>backfillUsersDisplayName</span><span class=p>)</span>
<span class=k>if</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
<span class=k>return</span> <span class=nx>err</span>
<span class=p>}</span>
<span class=nx>_</span><span class=p>,</span> <span class=nx>err</span> <span class=p>=</span> <span class=nx>tx</span><span class=p>.</span><span class=nx>ExecContext</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=nx>requireUsersDisplayName</span><span class=p>)</span>
<span class=k>return</span> <span class=nx>err</span>
<span class=p>}</span>
</code></pre></div>
<p>and then register this function in the migrations sequence:</p>
<div class=highlight><pre><span></span><code><span class=p>[]</span><span class=nx>golembic</span><span class=p>.</span><span class=nx>MigrationOption</span><span class=p>{</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptPrevious</span><span class=p>(</span><span class=s>"986b93c5e494"</span><span class=p>),</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptRevision</span><span class=p>(</span><span class=s>"f37715e564e5"</span><span class=p>),</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptDescription</span><span class=p>(</span><span class=s>"Backfill `users.display_name` column and make required"</span><span class=p>),</span>
<span class=nx>golembic</span><span class=p>.</span><span class=nx>OptUp</span><span class=p>(</span><span class=nx>RequiredDisplayName</span><span class=p>),</span>
<span class=p>},</span>
</code></pre></div>
<h3 id=guard-rails>Guard Rails</h3>
<p>If the next deploy targets the code after the second migration was merged,
the migrations tooling will refuse to run <strong>any</strong> of the migrations and
will cause a failure:</p>
<div class=highlight><pre><span></span><code>$ make run-postgres-cmd GOLEMBIC_CMD=describe
...
6 | 432f690fcbda | Create movies table
7 | 986b93c5e494 | Add optional `users.display_name` column [MILESTONE]
8 | f37715e564e5 | Backfill `users.display_name` column and make required
$
$ make run-postgres-cmd
If a migration sequence contains a milestone, it must be the last migration; revision 986b93c5e494 (1 / 2 migrations)
exit status 1
make: *** [run-postgres-cmd] Error 1
</code></pre></div>
<p>This indicates that the service operator should back the truck up and deploy
an earlier version, i.e. one where only the first migration and the
associated code changes are present:</p>
<div class=highlight><pre><span></span><code>$ make run-postgres-cmd GOLEMBIC_CMD=describe
...
6 | 432f690fcbda | Create movies table
7 | 986b93c5e494 | Add optional `users.display_name` column [MILESTONE]
$
$ make run-postgres-cmd
Applying 986b93c5e494: Add optional `users.display_name` column [MILESTONE]
</code></pre></div>
<p>After this <strong>milestone</strong> version stabilizes, the second migration can be run
and the associated code changes can be deployed:</p>
<div class=highlight><pre><span></span><code>$ make run-postgres-cmd
Applying f37715e564e5: Backfill `users.display_name` column and make required
</code></pre></div>
<h3 id=related>Related</h3>
<p>See <a href="/2021/10/database-migrations-table.html">The Case for a Metadata Table for Database Migrations</a> for more context
on how metadata tables for migrations work.</p>
<hr style="margin-bottom: 25px; width: 50%;"><ol class=simple-footnotes><li id=sf-database-migrations-milestone-1>What do we
mean by letting a deployment stabilize? Two things primarily: (1) the
rolling update has completed so that the old code isn't running and
(2) some form of acceptance testing to ensure the application doesn't need
to rollback to a previous version <a href=#sf-database-migrations-milestone-1-back class=simple-footnote-back>↩</a></li></ol>The Case for a Metadata Table for Database Migrations2021-10-29T00:00:00-07:002021-10-29T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-10-29:/2021/10/database-migrations-table.html<p><img alt="Tracking Migrations" src="/images/Legal_pad_and_pencil.jpg"></p>
<h3 id="motivation">Motivation</h3>
<p>As features are added, changed or deleted, the data model used by an
application usually changes as well. For most database-backed applications,
this means migrations are needed.</p>
<p>With this in mind, the fundamental goal of database migrations:</p>
<blockquote>
<p>The current database schema should match the currently running code.</p>
</blockquote>
<p>However, achieving …</p><p><img alt="Tracking Migrations" src="/images/Legal_pad_and_pencil.jpg"></p>
<h3 id="motivation">Motivation</h3>
<p>As features are added, changed or deleted, the data model used by an
application usually changes as well. For most database-backed applications,
this means migrations are needed.</p>
<p>With this in mind, the fundamental goal of database migrations:</p>
<blockquote>
<p>The current database schema should match the currently running code.</p>
</blockquote>
<p>However, achieving this goal is not so easy. A typical database migration
might be adding an index to improve performance of a common query:</p>
<div class="highlight"><pre><span></span><code><span class="k">CREATE</span> <span class="k">INDEX</span>
<span class="n">idx_books_publish_date</span>
<span class="k">ON</span>
<span class="n">books</span> <span class="p">(</span><span class="n">publish_date</span> <span class="k">DESC</span><span class="p">,</span> <span class="n">title</span> <span class="k">ASC</span><span class="p">);</span>
</code></pre></div>
<p>or adding a new column to support a new feature set:</p>
<div class="highlight"><pre><span></span><code><span class="k">ALTER</span> <span class="k">TABLE</span>
<span class="n">books</span>
<span class="k">ADD</span> <span class="k">COLUMN</span>
<span class="n">latest_edition</span> <span class="k">TIMESTAMP</span><span class="p">;</span>
</code></pre></div>
<p>In PostgreSQL, migrations like these are easy to write in an idempotent way</p>
<div class="highlight"><pre><span></span><code><span class="k">CREATE</span> <span class="k">INDEX</span> <span class="k">IF</span> <span class="k">NOT</span> <span class="k">EXISTS</span>
<span class="n">idx_books_publish_date</span>
<span class="k">ON</span>
<span class="n">books</span> <span class="p">(</span><span class="n">publish_date</span> <span class="k">DESC</span><span class="p">,</span> <span class="n">title</span> <span class="k">ASC</span><span class="p">);</span>
<span class="c1">---</span>
<span class="k">ALTER</span> <span class="k">TABLE</span>
<span class="n">books</span>
<span class="k">ADD</span> <span class="k">COLUMN</span> <span class="k">IF</span> <span class="k">NOT</span> <span class="k">EXISTS</span>
<span class="n">latest_edition</span> <span class="k">TIMESTAMP</span><span class="p">;</span>
</code></pre></div>
<p>But not all migrations are so simple. Some migrations involve backfilling
information:</p>
<div class="highlight"><pre><span></span><code><span class="k">UPDATE</span>
<span class="n">books</span>
<span class="k">SET</span>
<span class="n">latest_edition</span> <span class="o">=</span> <span class="n">publish_date</span><span class="p">;</span>
</code></pre></div>
<p>and running a migration like that multiple times would be problematic (e.g.
if the data has already been backfilled and the new code allows <code>publish_date</code>
and <code>latest_edition</code> to start to diverge).</p>
<p>This is where a metadata table for migrations comes in. By keeping a clear
record of which migrations were run (and when), we can ensure each migration
will be run <strong>exactly once</strong> during development and more crucially, in
production databases.</p>
<h3 id="guards">Guards</h3>
<p>One alternative to a migrations table: introduce queries that check if a
migration was already performed and <strong>guard</strong> against running it twice.</p>
<p>Some arguments against this strategy:</p>
<ul>
<li>Doing this for <strong>every migration</strong> introduced in the codebase is a lot of
extra work</li>
<li>This introduces an opportunity to make mistakes by writing buggy guards;
for teams with a mix of experienced and inexperienced database users,
writing guards <strong>correctly</strong> represents a real challenge</li>
<li>In order to do "exactly once" checks on some migrations (e.g. the backfill
one above), it may be necessary to introduce <strong>phantom</strong> columns to the
database as breadcrumbs indicating the migration occurred</li>
</ul>
<div class="highlight"><pre><span></span><code><span class="k">UPDATE</span>
<span class="n">books</span>
<span class="k">SET</span>
<span class="n">latest_edition</span> <span class="o">=</span> <span class="n">publish_date</span><span class="p">,</span>
<span class="n">latest_edition_backfill</span> <span class="o">=</span> <span class="k">TRUE</span>
<span class="k">WHERE</span>
<span class="n">latest_edition_backfill</span> <span class="o">=</span> <span class="k">FALSE</span><span class="p">;</span>
</code></pre></div>
<ul>
<li>Application invariants may change over time and invalidate guards that
were historically correct</li>
</ul>
<h3 id="in-practice">In Practice</h3>
<p>It's useful to have an example to understand <strong>how</strong> a migrations table is
constructed and how it fits into development and deployment. I'll use the
example migrations from my <code>golembic</code> <a href="https://github.com/dhermes/golembic/tree/2021.10.29">tool</a> as our example.</p>
<p>To get started, the development database needs to be running. In this stage,
there should be no tables yet because no migrations have run:</p>
<div class="highlight"><pre><span></span><code>$ make start-postgres
Network dev-network-golembic created.
Container dev-postgres-golembic started on port 18426.
...
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
480e5fce3e10 postgres:13.1-alpine "docker-entrypoint.s…" 54 seconds ago Up 52 seconds 0.0.0.0:18426->5432/tcp dev-postgres-golembic
$
$ make psql
Running psql against port 18426
psql "postgres://golembic_admin:testpassword_admin@127.0.0.1:18426/golembic"
...
golembic=> \dt
Did not find any relations.
golembic=> \q
</code></pre></div>
<p>Using <code>golembic</code>, we can run the migrations in the development database:</p>
<div class="highlight"><pre><span></span><code>$ make run-postgres-cmd
Applying c9b52448285b: Create users table
Applying f1be62155239: Seed data in users table
Applying dce8812d7b6f: Add city column to users table
Applying 0430566018cc: Rename the root user [MILESTONE]
Applying 0501ccd1d98c: Add index on user emails (concurrently)
Applying e2d4eecb1841: Create books table
Applying 432f690fcbda: Create movies table
</code></pre></div>
<p>At this point, the migrations will have created the three tables needed by
the application: <code>books</code>, <code>movies</code> and <code>users</code>. Observe via <code>make psql</code>:</p>
<div class="highlight"><pre><span></span><code><span class="gp">golembic=></span> <span class="kp">\dt</span>
<span class="go"> List of relations</span>
<span class="go"> Schema | Name | Type | Owner</span>
<span class="go">--------+---------------------+-------+----------------</span>
<span class="go"> public | books | table | golembic_admin</span>
<span class="go"> public | golembic_migrations | table | golembic_admin</span>
<span class="go"> public | movies | table | golembic_admin</span>
<span class="go"> public | users | table | golembic_admin</span>
<span class="go">(4 rows)</span>
</code></pre></div>
<p>In addition to the application tables from the migrations, there is also a
new metadata table <code>golembic_migrations</code>. This contains a record of the
migrations that have already been run:</p>
<div class="highlight"><pre><span></span><code><span class="gp">golembic=></span> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">golembic_migrations</span><span class="p">;</span>
<span class="go"> serial_id | revision | previous | created_at</span>
<span class="go">-----------+--------------+--------------+-------------------------------</span>
<span class="go"> 0 | c9b52448285b | | 2021-10-29 03:57:57.92535+00</span>
<span class="go"> 1 | f1be62155239 | c9b52448285b | 2021-10-29 03:57:57.936784+00</span>
<span class="go"> 2 | dce8812d7b6f | f1be62155239 | 2021-10-29 03:57:57.945764+00</span>
<span class="go"> 3 | 0430566018cc | dce8812d7b6f | 2021-10-29 03:57:57.954536+00</span>
<span class="go"> 4 | 0501ccd1d98c | 0430566018cc | 2021-10-29 03:57:57.963776+00</span>
<span class="go"> 5 | e2d4eecb1841 | 0501ccd1d98c | 2021-10-29 03:57:57.986174+00</span>
<span class="go"> 6 | 432f690fcbda | e2d4eecb1841 | 2021-10-29 03:57:57.9968+00</span>
<span class="go">(7 rows)</span>
<span class="gp">golembic=></span> <span class="kp">\q</span>
</code></pre></div>
<p>Using this record, the <strong>next time</strong> the migrations command runs, the
records in <code>golembic_migrations</code> can be used to determine that no new
migrations need to run:</p>
<div class="highlight"><pre><span></span><code>$ make run-postgres-cmd
No migrations to run; latest revision: 432f690fcbda
</code></pre></div>
<h3 id="prior-art">Prior Art</h3>
<p>Although it may seem like an advertisment for <code>golembic</code>, the point of this
post was to make a case for a migrations table. To see <code>golembic</code> isn't
alone, note that <a href="https://github.com/typeorm/typeorm">TypeORM</a> takes a similar approach. For example:</p>
<div class="highlight"><pre><span></span><code><span class="gp">dunder_mifflin=></span> <span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">migrations</span><span class="p">;</span>
<span class="go"> id | timestamp | name</span>
<span class="go">----+---------------+-----------------------------------------------</span>
<span class="go"> 1 | 1568674788742 | initial1568674788742</span>
<span class="go"> 2 | 1571783618350 | recipient1571783618350</span>
<span class="go"> 3 | 1572313444993 | recipientEnum1572313444993</span>
<span class="go"> 4 | 1572479127851 | ticket1572479127851</span>
<span class="go"> 5 | 1572990972108 | ticketIndex1572990972108</span>
<span class="go"> 6 | 1573594420208 | uniqueConstraint1573594420208</span>
<span class="go">(6 rows)</span>
<span class="gp">dunder_mifflin=></span> <span class="kp">\q</span>
</code></pre></div>
<p>(There are lots of ORMs and migrations tools other than TypeORM that also take
the same approach, I just had this example handy.)</p>When Elementary Becomes Elliptic2021-10-23T00:00:00-07:002021-10-23T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-10-23:/2021/10/elementary-elliptic.html<p>I enjoy watching math videos targeted at advanced high school or undergraduate
students — even if the topics are far away from research level
mathematics. I was recently watching a "quick and easy challenge in
algebra" <a href="https://youtu.be/Wy_uzVX1U_g">video</a> from <a href="https://www.youtube.com/c/SyberMath/videos">SyberMath</a><sup id=sf-elementary-elliptic-1-back><a href=#sf-elementary-elliptic-1 class=simple-footnote title="I also really enjoy Michael Penn videos.">1</a></sup> that used a neat trick to solve the problem.
As the …</p><p>I enjoy watching math videos targeted at advanced high school or undergraduate
students — even if the topics are far away from research level
mathematics. I was recently watching a "quick and easy challenge in
algebra" <a href="https://youtu.be/Wy_uzVX1U_g">video</a> from <a href="https://www.youtube.com/c/SyberMath/videos">SyberMath</a><sup id=sf-elementary-elliptic-1-back><a href=#sf-elementary-elliptic-1 class=simple-footnote title="I also really enjoy Michael Penn videos.">1</a></sup> that used a neat trick to solve the problem.
As the video title hints, this could've been a homework problem for advanced
high schoolers. In the video, SyberMath makes an <strong>offhand</strong> comment:</p>
<blockquote>
<p>Notice that the original expression is equal to one and obviously you can
find some numbers that satisfy this, right?</p>
</blockquote>
<p>The ensuing proof in the video shows that an identity holds for <strong>all</strong>
values, so the task of "find some numbers" never actually happens. However,
this comment stuck with me and I tried to find the "simplest" numbers that
would make that expression equal one. Going down this path I accidentally
waded<sup id=sf-elementary-elliptic-2-back><a href=#sf-elementary-elliptic-2 class=simple-footnote title="I actually consulted my great friend Wade when wading into these deep waters.">2</a></sup> into deep waters with advanced number theory concepts.</p>
<h3>Contents</h3>
<ul>
<li><a href=#original-problem>Original Problem</a></li>
<li><a href=#reduction>Reduction</a></li>
<li><a href=#wild-elliptic-curve>A Wild Elliptic Curve Appears</a></li>
<li><a href=#bad-news>Bad News</a></li>
<li><a href=#next-best-thing>The Next Best Thing</a></li>
<li><a href=#the-end>The End</a></li>
</ul>
<h3 id=original-problem>Original Problem</h3>
<p>The original problem statement<sup id=sf-elementary-elliptic-3-back><a href=#sf-elementary-elliptic-3 class=simple-footnote title="I have swapped out the variable names used in the video since I'll be introducing many more variables in this post.">3</a></sup>
is as follows. Given</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mfrac><mi>a</mi><mrow><mi>b</mi><mo>+</mo><mi>c</mi></mrow></mfrac><mo>+</mo><mfrac><mi>b</mi><mrow><mi>c</mi><mo>+</mo><mi>a</mi></mrow></mfrac><mo>+</mo><mfrac><mi>c</mi><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></mfrac><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\frac{a}{b + c} + \frac{b}{c + a} + \frac{c}{a + b} = 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.8768900000000002em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">c</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.14077em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.37144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">a</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.8768900000000002em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span></span>
</blockquote></div>
<p>show:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mfrac><msup><mi>a</mi><mn>2</mn></msup><mrow><mi>b</mi><mo>+</mo><mi>c</mi></mrow></mfrac><mo>+</mo><mfrac><msup><mi>b</mi><mn>2</mn></msup><mrow><mi>c</mi><mo>+</mo><mi>a</mi></mrow></mfrac><mo>+</mo><mfrac><msup><mi>c</mi><mn>2</mn></msup><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></mfrac><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\frac{a^2}{b + c} + \frac{b^2}{c + a} + \frac{c^2}{a + b} = 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:2.260438em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.491108em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">c</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.260438em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.491108em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">a</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">b</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.260438em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.491108em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">c</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span></span>
</blockquote></div>
<p>This blog post will focus on finding triples <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo separator=true>,</mo><mi>b</mi><mo separator=true>,</mo><mi>c</mi></mrow><annotation encoding="application/x-tex">a, b, c</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">a</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">b</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">c</span></span></span></span> that
satisfy the first equation. I was <strong>hoping</strong> I could find a solution in
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi mathvariant=bold>Q</mi><mn>3</mn></msup></mrow><annotation encoding="application/x-tex">\mathbf{Q}^3</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.008548em;vertical-align:-0.19444em;></span><span class=mord><span class="mord mathbf">Q</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span></span> but as we'll see below this is
<strong>impossible</strong>!</p>
<h3 id=reduction>Reduction</h3>
<p><strong>TL;DR</strong> we reduce to two degrees of freedom via</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign=center columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mi>s</mi><mo>=</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>c</mi><mo separator=true>,</mo><mi>p</mi><mo>=</mo><mfrac><mi>a</mi><mi>s</mi></mfrac><mo separator=true>,</mo><mi>q</mi><mo>=</mo><mfrac><mi>b</mi><mi>s</mi></mfrac></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mfrac><mn>1</mn><mrow><mn>1</mn><mo>−</mo><mi>p</mi></mrow></mfrac><mo>+</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>−</mo><mi>q</mi></mrow></mfrac><mo>+</mo><mfrac><mn>1</mn><mrow><mi>p</mi><mo>+</mo><mi>q</mi></mrow></mfrac><mo>=</mo><mn>4</mn></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{gather*}s = a + b + c, p = \frac{a}{s}, q = \frac{b}{s} \\ \frac{1}{1 - p} + \frac{1}{1 - q} + \frac{1}{p + q} = 4\end{gather*}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:4.85932em;vertical-align:-2.17966em;></span><span class=mord><span class=mtable><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.67966em;><span style=top:-4.67966em;><span class=pstrut style=height:3.3714399999999998em;></span><span class=mord><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">c</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.37144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style=top:-2.3722199999999996em;><span class=pstrut style=height:3.3714399999999998em;></span><span class=mord><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">p</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.8804400000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.8804400000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.8804400000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>4</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.17966em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<!--
import matplotlib # matplotlib==3.3.4
import matplotlib.pyplot as plt
import numpy as np # numpy==1.20.1
import seaborn # seaborn==0.11.1
def discriminant(p_vals):
# (p + 1)(4p - 3)(4 p^2 - 3p + 1) = 16 p^4 - 8 p^3 - 11 p^2 + 10p - 3
return (((16 * p_vals - 8) * p_vals - 11) * p_vals + 10) * p_vals - 3
def get_q_vals(p_vals):
delta = discriminant(p_vals)
sqrt_delta = np.sqrt(delta)
numerator_vals = (1 - p_vals) * (3 - 4 * p_vals)
denominator_vals = 2 * (3 - 4 * p_vals)
q_plus = (numerator_vals + sqrt_delta) / denominator_vals
q_minus = (numerator_vals - sqrt_delta) / denominator_vals
return q_plus, q_minus
def main():
# Python 3.9.1
seaborn.set()
matplotlib.rcParams["text.usetex"] = "true"
matplotlib.rcParams["mathtext.fontset"] = "cm"
matplotlib.rcParams["mathtext.rm"] = "serif"
figure = plt.figure()
ax = figure.gca()
p_vals_left = np.linspace(-5.0, -1.0, 1025)[::-1]
p_vals_right = np.linspace(0.75, 4.75, 1025)[1::]
q_plus_left, q_minus_left = get_q_vals(p_vals_left)
q_plus_right, q_minus_right = get_q_vals(p_vals_right)
(line,) = ax.plot(p_vals_left, q_plus_left)
ax.plot(p_vals_left, q_minus_left, color=line.get_color())
ax.plot(p_vals_right, q_plus_right, color=line.get_color())
ax.plot(p_vals_right, q_minus_right, color=line.get_color())
ax.plot(
[-1.0, 1.0, 1.0],
[1.0, -1.0, 1.0],
marker="o",
color="black",
linestyle="none",
)
ax.text(
1.5,
-0.75,
"$(1, -1)$",
fontsize=12,
verticalalignment="top",
horizontalalignment="left",
)
ax.text(
-0.75,
0.75,
"$(-1, 1)$",
fontsize=12,
verticalalignment="top",
horizontalalignment="right",
)
ax.text(
1.5,
1.5,
"$(1, 1)$",
fontsize=12,
verticalalignment="center",
horizontalalignment="center",
)
ax.set_xlabel("$p$", fontsize=16)
ax.set_ylabel("$q$", rotation=0, fontsize=16)
ax.axis("scaled")
figure.set_size_inches(12.8, 9.6)
figure.savefig("elementary-elliptic-pq.png", bbox_inches="tight")
plt.close(figure)
if __name__ == "__main__":
main()
-->
<div style="text-align: center;">
<p><img alt="Plot p-q" src="/images/elementary-elliptic-pq.png"></p>
</div>
<p>Feel free to skip to the next section if you don't care how or why we can
make this reduction.</p>
<p>Since the equation has three unknowns and one constraint, we expect the
solution to be a family with two degrees of freedom, so we want to first
reduce it. Note that this equation is homogeneous; scaling
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo separator=true>,</mo><mi>b</mi><mo separator=true>,</mo><mi>c</mi></mrow><annotation encoding="application/x-tex">a, b, c</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">a</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">b</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">c</span></span></span></span> to
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mi>a</mi><mo separator=true>,</mo><mi>λ</mi><mi>b</mi><mo separator=true>,</mo><mi>λ</mi><mi>c</mi></mrow><annotation encoding="application/x-tex">\lambda a, \lambda b, \lambda c</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">λa</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">λb</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">λ</span><span class="mord mathnormal">c</span></span></span></span> for any
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mo mathvariant=normal>≠</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\lambda \neq 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">λ</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><span class=mrel><span class="mord vbox"><span class=thinbox><span class=rlap><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=inner><span class=mord><span class=mrel></span></span></span><span class=fix></span></span></span></span></span><span class=mrel>=</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span> will preserve the relationship.</p>
<p>For the expression to be well-defined we must have
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>+</mo><mi>b</mi><mo mathvariant=normal>≠</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">a + b \neq 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.66666em;vertical-align:-0.08333em;></span><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><span class=mrel><span class="mord vbox"><span class=thinbox><span class=rlap><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=inner><span class=mord><span class=mrel></span></span></span><span class=fix></span></span></span></span></span><span class=mrel>=</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span> (and similar for the other permuted
denominators). With this out of the way we'll incorporate
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mo>=</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>c</mi></mrow><annotation encoding="application/x-tex">s = a + b + c</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.66666em;vertical-align:-0.08333em;></span><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.77777em;vertical-align:-0.08333em;></span><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">c</span></span></span></span> into the original equation in a fashion
similar to the trick in the video:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mi>s</mi><mrow><mo fence=true>(</mo><mfrac><mn>1</mn><mrow><mi>s</mi><mo>−</mo><mi>a</mi></mrow></mfrac><mo>+</mo><mfrac><mn>1</mn><mrow><mi>s</mi><mo>−</mo><mi>b</mi></mrow></mfrac><mo>+</mo><mfrac><mn>1</mn><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></mfrac><mo fence=true>)</mo></mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mfrac><mi>a</mi><mrow><mi>b</mi><mo>+</mo><mi>c</mi></mrow></mfrac><mo>+</mo><mfrac><mrow><mi>b</mi><mo>+</mo><mi>c</mi></mrow><mrow><mi>b</mi><mo>+</mo><mi>c</mi></mrow></mfrac><mo>+</mo><mo>⋯</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mfrac><mi>a</mi><mrow><mi>b</mi><mo>+</mo><mi>c</mi></mrow></mfrac><mo>+</mo><mfrac><mi>b</mi><mrow><mi>c</mi><mo>+</mo><mi>a</mi></mrow></mfrac><mo>+</mo><mfrac><mi>c</mi><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></mfrac><mo>+</mo><mn>3</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mn>4.</mn></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} s\left(\frac{1}{s - a} + \frac{1}{s - b} + \frac{1}{a + b}\right) &= \frac{a}{b + c} + \frac{b + c}{b + c} + \cdots \\ &= \frac{a}{b + c} + \frac{b}{c + a} + \frac{c}{a + b} + 3 \\ &= 4.\end{aligned}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:6.6408em;vertical-align:-3.0704em;></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:3.5704em;><span style=top:-5.570400000000001em;><span class=pstrut style=height:3.45em;></span><span class=mord><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">a</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span></span></span><span style=top:-2.9489300000000007em;><span class=pstrut style=height:3.45em;></span><span class=mord></span></span><span style=top:-1.0396000000000005em;><span class=pstrut style=height:3.45em;></span><span class=mord></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:3.0704em;><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:3.5704em;><span style=top:-5.570400000000001em;><span class=pstrut style=height:3.45em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">c</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.37144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">c</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">c</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=minner>⋯</span></span></span><span style=top:-2.9489300000000007em;><span class=pstrut style=height:3.45em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">c</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.37144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">a</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>3</span></span></span><span style=top:-1.0396000000000005em;><span class=pstrut style=height:3.45em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>4.</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:3.0704em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>We must have <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo mathvariant=normal>≠</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">a \neq 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><span class=mrel><span class="mord vbox"><span class=thinbox><span class=rlap><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=inner><span class=mord><span class=mrel></span></span></span><span class=fix></span></span></span></span></span><span class=mrel>=</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span> and by symmetry
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo mathvariant=normal>≠</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">b \neq 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><span class=mrel><span class="mord vbox"><span class=thinbox><span class=rlap><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=inner><span class=mord><span class=mrel></span></span></span><span class=fix></span></span></span></span></span><span class=mrel>=</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span> and <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mo mathvariant=normal>≠</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">c \neq 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">c</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><span class=mrel><span class="mord vbox"><span class=thinbox><span class=rlap><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=inner><span class=mord><span class=mrel></span></span></span><span class=fix></span></span></span></span></span><span class=mrel>=</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span>. By way of
contradiction, if <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">a = 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span>:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mfrac><mi>b</mi><mi>c</mi></mfrac><mo>+</mo><mfrac><mi>c</mi><mi>b</mi></mfrac><mo>=</mo><mn>1</mn><mtext> </mtext><mo>⟹</mo><mtext> </mtext><mfrac><mi>b</mi><mi>c</mi></mfrac><mo>=</mo><mfrac><mrow><mn>1</mn><mo>±</mo><mi>i</mi><msqrt><mn>3</mn></msqrt></mrow><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{b}{c} + \frac{c}{b} = 1 \implies \frac{b}{c} = \frac{1 \pm i \sqrt{3}}{2}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:2.05744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.37144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.7935600000000003em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.66844em;vertical-align:-0.024em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟹</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.05744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.37144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.27022em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.5842200000000002em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>±</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">i</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.90722em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>3</span></span></span><span style=top:-2.86722em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.13278em;><span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>which can't happen since <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo separator=true>,</mo><mi>c</mi><mo>∈</mo><mi mathvariant=bold>R</mi></mrow><annotation encoding="application/x-tex">b, c \in \mathbf{R}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">b</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">c</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>∈</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.68611em;vertical-align:0em;></span><span class="mord mathbf">R</span></span></span></span>.
Using this, we can finally show <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mo mathvariant=normal>≠</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">s \neq 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><span class=mrel><span class="mord vbox"><span class=thinbox><span class=rlap><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=inner><span class=mord><span class=mrel></span></span></span><span class=fix></span></span></span></span></span><span class=mrel>=</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span>; again
by way of contradiction, if <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">s = 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span>:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mfrac><mi>a</mi><mrow><mi>s</mi><mo>−</mo><mi>a</mi></mrow></mfrac><mo>+</mo><mo>⋯</mo><mo>=</mo><mfrac><mi>a</mi><mrow><mo>−</mo><mi>a</mi></mrow></mfrac><mo>+</mo><mfrac><mi>b</mi><mrow><mo>−</mo><mi>b</mi></mrow></mfrac><mo>+</mo><mfrac><mi>c</mi><mrow><mo>−</mo><mi>c</mi></mrow></mfrac><mo>=</mo><mo>−</mo><mn>3</mn><mo mathvariant=normal>≠</mo><mn>1.</mn></mrow><annotation encoding="application/x-tex">\frac{a}{s - a} + \cdots = \frac{a}{-a} + \frac{b}{-b} + \frac{c}{-c} = -3 \neq 1.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.8768900000000002em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">a</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.36687em;vertical-align:0em;></span><span class=minner>⋯</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.8768900000000002em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>−</span><span class="mord mathnormal">a</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.14077em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.37144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>−</span><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">b</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.8768900000000002em;vertical-align:-0.7693300000000001em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>−</span><span class="mord mathnormal">c</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">c</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=mord>−</span><span class=mord>3</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel><span class=mrel><span class="mord vbox"><span class=thinbox><span class=rlap><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=inner><span class=mord><span class=mrel></span></span></span><span class=fix></span></span></span></span></span><span class=mrel>=</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1.</span></span></span></span></span>
</blockquote></div>
<p>Now we can safely divide by <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi></mrow><annotation encoding="application/x-tex">s</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">s</span></span></span></span> to make an equation with our
two free parameters:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mn>4</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mfrac><mi>s</mi><mrow><mi>s</mi><mo>−</mo><mi>a</mi></mrow></mfrac><mo>+</mo><mfrac><mi>s</mi><mrow><mi>s</mi><mo>−</mo><mi>b</mi></mrow></mfrac><mo>+</mo><mfrac><mi>s</mi><mrow><mi>a</mi><mo>+</mo><mi>b</mi></mrow></mfrac></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>−</mo><mi>a</mi><mi mathvariant=normal>/</mi><mi>s</mi></mrow></mfrac><mo>+</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>−</mo><mi>b</mi><mi mathvariant=normal>/</mi><mi>s</mi></mrow></mfrac><mo>+</mo><mfrac><mn>1</mn><mrow><mi>a</mi><mi mathvariant=normal>/</mi><mi>s</mi><mo>+</mo><mi>b</mi><mi mathvariant=normal>/</mi><mi>s</mi></mrow></mfrac><mi mathvariant=normal>.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} 4 &= \frac{s}{s - a} + \frac{s}{s - b} + \frac{s}{a + b} \\ &= \frac{1}{1 - a/s} + \frac{1}{1 - b/s} + \frac{1}{a/s + b/s}.\end{aligned}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:4.73433em;vertical-align:-2.117165em;></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.617165em;><span style=top:-4.831045em;><span class=pstrut style=height:3.32144em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-2.440275em;><span class=pstrut style=height:3.32144em;></span><span class=mord></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.117165em;><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.617165em;><span style=top:-4.831045em;><span class=pstrut style=height:3.32144em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">a</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.10756em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">s</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style=top:-2.440275em;><span class=pstrut style=height:3.32144em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">a</span><span class=mord>/</span><span class="mord mathnormal">s</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span><span class=mord>/</span><span class="mord mathnormal">s</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal">a</span><span class=mord>/</span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">b</span><span class=mord>/</span><span class="mord mathnormal">s</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord>.</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.117165em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<h3 id=wild-elliptic-curve>A Wild Elliptic Curve Appears</h3>
<p>Clearing denominators in our equation we can form a quadratic in
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span></span>:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mo stretchy=false>(</mo><mn>3</mn><mo>−</mo><mn>4</mn><mi>p</mi><mo stretchy=false>)</mo><msup><mi>q</mi><mn>2</mn></msup><mo>−</mo><mo stretchy=false>(</mo><mn>1</mn><mo>−</mo><mi>p</mi><mo stretchy=false>)</mo><mo stretchy=false>(</mo><mn>3</mn><mo>−</mo><mn>4</mn><mi>p</mi><mo stretchy=false>)</mo><mi>q</mi><mo>+</mo><mrow><mo fence=true>(</mo><mn>3</mn><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>3</mn><mi>p</mi><mo>+</mo><mn>1</mn><mo fence=true>)</mo></mrow><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">(3 - 4p) q^2 - (1 - p)(3 - 4p) q + \left(3 p^2 - 3p + 1\right) = 0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mopen>(</span><span class=mord>3</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.1141079999999999em;vertical-align:-0.25em;></span><span class=mord>4</span><span class="mord mathnormal">p</span><span class=mclose>)</span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mopen>(</span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal">p</span><span class=mclose>)</span><span class=mopen>(</span><span class=mord>3</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mord>4</span><span class="mord mathnormal">p</span><span class=mclose>)</span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.2141179999999998em;vertical-align:-0.35001em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">(</span></span><span class=mord>3</span><span class=mord><span class="mord mathnormal">p</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>3</span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">)</span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span></span>
</blockquote></div>
<p>which has solutions:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>q</mi><mo>=</mo><mfrac><mrow><mo stretchy=false>(</mo><mn>1</mn><mo>−</mo><mi>p</mi><mo stretchy=false>)</mo><mo stretchy=false>(</mo><mn>3</mn><mo>−</mo><mn>4</mn><mi>p</mi><mo stretchy=false>)</mo><mo>±</mo><msqrt><mi mathvariant=normal>Δ</mi></msqrt></mrow><mrow><mn>2</mn><mo stretchy=false>(</mo><mn>3</mn><mo>−</mo><mn>4</mn><mi>p</mi><mo stretchy=false>)</mo></mrow></mfrac><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">q = \frac{(1 - p)(3 - 4p) \pm \sqrt{\Delta}}{2(3 - 4p)}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.5396650000000003em;vertical-align:-0.936em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.6036650000000001em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span><span class=mopen>(</span><span class=mord>3</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>4</span><span class="mord mathnormal">p</span><span class=mclose>)</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mopen>(</span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">p</span><span class=mclose>)</span><span class=mopen>(</span><span class=mord>3</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>4</span><span class="mord mathnormal">p</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>±</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.9266650000000001em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>Δ</span></span></span><span style=top:-2.886665em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.11333499999999996em;><span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>Given a rational <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal">p</span></span></span></span> we only have rational
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span></span> if the discriminant is the square of a rational:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msup><mi>d</mi><mn>2</mn></msup><mo>=</mo><mi mathvariant=normal>Δ</mi><mo>=</mo><mrow><mo fence=true>(</mo><mi>p</mi><mo>+</mo><mn>1</mn><mo fence=true>)</mo></mrow><mrow><mo fence=true>(</mo><mn>4</mn><mi>p</mi><mo>−</mo><mn>3</mn><mo fence=true>)</mo></mrow><mrow><mo fence=true>(</mo><mn>4</mn><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>3</mn><mi>p</mi><mo>+</mo><mn>1</mn><mo fence=true>)</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">d^2 = \Delta = \left(p + 1\right) \left(4p - 3\right) \left(4 p^2 - 3p + 1\right).</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8641079999999999em;vertical-align:0em;></span><span class=mord><span class="mord mathnormal">d</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class=mord>Δ</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.2141179999999998em;vertical-align:-0.35001em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord>4</span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>3</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">(</span></span><span class=mord>4</span><span class=mord><span class="mord mathnormal">p</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>3</span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">)</span></span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>Thanks to a helpful <a href="https://mathoverflow.net/a/239752/40609">tip</a> to use a <a href="https://en.wikipedia.org/wiki/M%C3%B6bius_transformation">Möbius transformation</a>, we can
transform via</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>d</mi><mo>=</mo><mfrac><mrow><mn>63</mn><mi>y</mi></mrow><mrow><mo stretchy=false>(</mo><mn>3</mn><mi>x</mi><mo>−</mo><mn>25</mn><msup><mo stretchy=false>)</mo><mn>2</mn></msup></mrow></mfrac><mo separator=true>,</mo><mi>p</mi><mo>=</mo><mfrac><mrow><mn>9</mn><mo stretchy=false>(</mo><mi>x</mi><mo>+</mo><mn>1</mn><mo stretchy=false>)</mo></mrow><mrow><mn>4</mn><mo stretchy=false>(</mo><mn>3</mn><mi>x</mi><mo>−</mo><mn>25</mn><mo stretchy=false>)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">d = \frac{63y}{(3x - 25)^2}, p = \frac{9(x + 1)}{4(3x - 25)}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.69444em;vertical-align:0em;></span><span class="mord mathnormal">d</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.25744em;vertical-align:-0.936em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>25</span><span class=mclose><span class=mclose>)</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.740108em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>63</span><span class="mord mathnormal" style=margin-right:0.03588em;>y</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.363em;vertical-align:-0.936em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.427em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>25</span><span class=mclose>)</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>9</span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class=mclose>)</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>which produces an <a href="https://en.wikipedia.org/wiki/Elliptic_curve">elliptic curve</a> in Weierstrass form:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msup><mi>y</mi><mn>2</mn></msup><mo>=</mo><msup><mi>x</mi><mn>3</mn></msup><mo>+</mo><mfrac><mn>215</mn><mn>3</mn></mfrac><mi>x</mi><mo>−</mo><mfrac><mn>10582</mn><mn>27</mn></mfrac><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">y^2 = x^3 + \frac{215}{3} x - \frac{10582}{27}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.0585479999999998em;vertical-align:-0.19444em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em;>y</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.9474379999999999em;vertical-align:-0.08333em;></span><span class=mord><span class="mord mathnormal">x</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>215</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>27</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>10582</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>In other words, rational solutions
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence=true>(</mo><mi>a</mi><mo separator=true>,</mo><mi>b</mi><mo separator=true>,</mo><mi>c</mi><mo fence=true>)</mo></mrow><mo>∈</mo><msup><mi mathvariant=bold>Q</mi><mn>3</mn></msup></mrow><annotation encoding="application/x-tex">\left(a, b, c\right) \in \mathbf{Q}^3</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal">a</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">b</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">c</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>∈</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.008548em;vertical-align:-0.19444em;></span><span class=mord><span class="mord mathbf">Q</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span></span> correspond to
rational solutions <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence=true>(</mo><mi>p</mi><mo separator=true>,</mo><mi>q</mi><mo fence=true>)</mo></mrow><mo>∈</mo><msup><mi mathvariant=bold>Q</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">\left(p, q\right) \in \mathbf{Q}^2</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal">p</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>∈</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.008548em;vertical-align:-0.19444em;></span><span class=mord><span class="mord mathbf">Q</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>
which in turn correspond to rational points
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence=true>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo fence=true>)</mo></mrow><annotation encoding="application/x-tex">\left(x, y\right)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>y</span><span class="mclose delimcenter" style=top:0em;>)</span></span></span></span></span> on this elliptic curve.</p>
<h3 id=bad-news>Bad News</h3>
<!--
import matplotlib # matplotlib==3.3.4
import matplotlib.pyplot as plt
import numpy as np # numpy==1.20.1
import seaborn # seaborn==0.11.1
def get_y_vals(x_vals):
y_squared = ((27 * x_vals * x_vals + 215 * 9) * x_vals - 10582) / 27
y_plus = np.sqrt(y_squared)
y_minus = -y_plus
return y_plus, y_minus
def main():
# Python 3.9.1
seaborn.set()
matplotlib.rcParams["text.usetex"] = "true"
matplotlib.rcParams["mathtext.fontset"] = "cm"
matplotlib.rcParams["mathtext.rm"] = "serif"
figure = plt.figure()
ax = figure.gca()
x_vals = np.linspace(13.0, 120.0, 1025) / 3.0
y_plus, y_minus = get_y_vals(x_vals)
(line,) = ax.plot(x_vals, y_plus)
ax.plot(x_vals, y_minus, color=line.get_color())
ax.plot(
[13.0 / 3.0, 25.0 / 3.0, 25.0 / 3.0, 109.0 / 3.0, 109.0 / 3.0],
[0.0, 28.0, -28.0, 224.0, -224.0],
marker="o",
color="black",
linestyle="none",
)
ax.text(
4.25,
-10.0,
r"$\left(\frac{13}{3}, 0\right)$",
fontsize=18,
verticalalignment="top",
horizontalalignment="center",
)
ax.text(
8.25,
-35.0,
r"$\left(\frac{25}{3}, -28\right)$",
fontsize=18,
verticalalignment="top",
horizontalalignment="center",
)
ax.text(
8.25,
35.0,
r"$\left(\frac{25}{3}, 28\right)$",
fontsize=18,
verticalalignment="bottom",
horizontalalignment="center",
)
ax.text(
36.25,
-240.0,
r"$\left(\frac{109}{3}, -224\right)$",
fontsize=18,
verticalalignment="top",
horizontalalignment="center",
)
ax.text(
36.25,
240.0,
r"$\left(\frac{109}{3}, 224\right)$",
fontsize=18,
verticalalignment="bottom",
horizontalalignment="center",
)
ax.set_xlabel("$x$", fontsize=24)
ax.set_ylabel("$y$", rotation=0, fontsize=24)
figure.set_size_inches(12.8, 9.6)
figure.savefig("elementary-elliptic-xy.png", bbox_inches="tight")
plt.close(figure)
if __name__ == "__main__":
main()
-->
<div style="text-align: center;">
<p><img alt="Plot x-y" src="/images/elementary-elliptic-xy.png"></p>
</div>
<p>In general, finding rational points on an elliptic curve (and proving you have
found them all) is a challenge. Luckily <a href="http://magma.maths.usyd.edu.au/calc/">MAGMA</a> exists and the helpful
mathematicians on the internet want you to <a href="https://math.stackexchange.com/a/1330867/31956">know</a>. Plugging in our curve</p>
<div class=highlight><pre><span></span><code><span class=nt>E</span><span class=o>:=</span><span class=nt>EllipticCurve</span><span class=o>(</span><span class=cp>[</span><span class=mi>215</span> <span class=o>/</span> <span class=mi>3</span><span class=p>,</span> <span class=o>-</span> <span class=mi>10582</span> <span class=o>/</span> <span class=mi>27</span><span class=cp>]</span><span class=o>);</span>
<span class=nt>MordellWeilGroup</span><span class=o>(</span><span class=nt>E</span><span class=o>);</span>
<span class=nt>RationalPoints</span><span class=o>(</span><span class=nt>E</span> <span class=o>:</span> <span class=nt>Bound</span><span class=o>:=</span><span class=nt>1000</span><span class=o>);</span>
</code></pre></div>
<p>we find that there are only <strong>six</strong> rational points on the curve (including
the point at infinity, which requires looking for points in projective space).
These points are isomorphic to <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>Z</mi><mi mathvariant=normal>/</mi><mn>6</mn><mi mathvariant=bold>Z</mi></mrow><annotation encoding="application/x-tex">\mathbf{Z}/6\mathbf{Z}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathbf">Z</span><span class=mord>/6</span><span class="mord mathbf">Z</span></span></span></span>
under addition on the curve, so a single generator is enough to describe
the points. Using projective coordinates <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>=</mo><mi>X</mi><mi mathvariant=normal>/</mi><mi>Z</mi><mo separator=true>,</mo><mi>y</mi><mo>=</mo><mi>Y</mi><mi mathvariant=normal>/</mi><mi>Z</mi></mrow><annotation encoding="application/x-tex">x = X/Z, y = Y/Z</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>y</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.22222em;>Y</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span></span></span></span>
we can start with one of the two generators:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><msub><mi>P</mi><mn>1</mn></msub></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mrow><mo fence=true>[</mo><mn>109</mn><mo>:</mo><mn>672</mn><mo>:</mo><mn>3</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>2</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mrow><mo fence=true>[</mo><mn>25</mn><mo>:</mo><mn>84</mn><mo>:</mo><mn>3</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>3</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mrow><mo fence=true>[</mo><mn>13</mn><mo>:</mo><mn>0</mn><mo>:</mo><mn>3</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>4</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mrow><mo fence=true>[</mo><mn>25</mn><mo>:</mo><mo>−</mo><mn>84</mn><mo>:</mo><mn>3</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>5</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mrow><mo fence=true>[</mo><mn>109</mn><mo>:</mo><mo>−</mo><mn>672</mn><mo>:</mo><mn>3</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>6</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mrow><mo fence=true>[</mo><mn>0</mn><mo>:</mo><mn>1</mn><mo>:</mo><mn>0</mn><mo fence=true>]</mo></mrow><mi mathvariant=normal>.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}P_1 &= \left[ 109 : 672 : 3 \right] \\ 2P_1 &= \left[ 25 : 84 : 3 \right] \\ 3P_1 &= \left[ 13 : 0 : 3 \right] \\ 4P_1 &= \left[ 25 : -84 : 3 \right] \\ 5P_1 &= \left[ 109 : -672 : 3 \right] \\ 6P_1 &= \left[ 0 : 1 : 0 \right].\end{aligned}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:9.000000000000002em;vertical-align:-4.250000000000001em;></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:4.750000000000001em;><span style=top:-6.910000000000001em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:-5.41em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:-3.9099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:-2.4099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:-0.9099999999999997em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>5</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:0.5900000000000007em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>6</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:4.250000000000001em;><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:4.750000000000001em;><span style=top:-6.910000000000001em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>109</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>672</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>3</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-5.41em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>25</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>84</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>3</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-3.9099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>13</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>0</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>3</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-2.4099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>25</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>−</span><span class=mord>84</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>3</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-0.9099999999999997em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>109</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>−</span><span class=mord>672</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>3</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:0.5900000000000007em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>0</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>0</span><span class="mclose delimcenter" style=top:0em;>]</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:4.250000000000001em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Since we'd like to convert these back to solutions <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo separator=true>,</mo><mi>q</mi></mrow><annotation encoding="application/x-tex">p, q</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal">p</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span></span>
we want to represent these points in terms of
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence=true>[</mo><mi>X</mi><mo>:</mo><mi>Y</mi><mo>:</mo><mi>Z</mi><mo fence=true>]</mo></mrow><annotation encoding="application/x-tex">\left[ X : Y : Z \right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.22222em;>Y</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span></span>. Plugging in our transformations
for <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal">p</span></span></span></span> and <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi></mrow><annotation encoding="application/x-tex">d</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.69444em;vertical-align:0em;></span><span class="mord mathnormal">d</span></span></span></span> we have</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>p</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mn>9</mn><mo stretchy=false>(</mo><mi>x</mi><mo>+</mo><mn>1</mn><mo stretchy=false>)</mo></mrow><mrow><mn>4</mn><mo stretchy=false>(</mo><mn>3</mn><mi>x</mi><mo>−</mo><mn>25</mn><mo stretchy=false>)</mo></mrow></mfrac><mo>=</mo><mfrac><mrow><mn>18</mn><mo stretchy=false>(</mo><mi>X</mi><mo>+</mo><mi>Z</mi><mo stretchy=false>)</mo></mrow><mrow><mn>8</mn><mo stretchy=false>(</mo><mn>3</mn><mi>X</mi><mo>−</mo><mn>25</mn><mi>Z</mi><mo stretchy=false>)</mo></mrow></mfrac></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>q</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mn>3</mn><mi>x</mi><mo>−</mo><mn>109</mn><mo>±</mo><mn>3</mn><mi>y</mi></mrow><mrow><mn>8</mn><mo stretchy=false>(</mo><mn>3</mn><mi>x</mi><mo>−</mo><mn>25</mn><mo stretchy=false>)</mo></mrow></mfrac><mo>=</mo><mfrac><mrow><mn>3</mn><mi>X</mi><mo>−</mo><mn>109</mn><mi>Z</mi><mo>±</mo><mn>3</mn><mi>Y</mi></mrow><mrow><mn>8</mn><mo stretchy=false>(</mo><mn>3</mn><mi>X</mi><mo>−</mo><mn>25</mn><mi>Z</mi><mo stretchy=false>)</mo></mrow></mfrac><mi mathvariant=normal>.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}p &= \frac{9(x + 1)}{4(3x - 25)} = \frac{18(X + Z)}{8(3X - 25Z)} \\ q &= \frac{3x - 109 \pm 3y}{8(3x - 25)} = \frac{3X - 109Z \pm 3Y}{8(3X - 25Z)}.\end{aligned}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:5.25933em;vertical-align:-2.379665em;></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.879665em;><span style=top:-4.879665em;><span class=pstrut style=height:3.427em;></span><span class=mord><span class="mord mathnormal">p</span></span></span><span style=top:-2.283335em;><span class=pstrut style=height:3.427em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.379665em;><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.879665em;><span style=top:-4.879665em;><span class=pstrut style=height:3.427em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.427em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>25</span><span class=mclose>)</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>9</span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class=mclose>)</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.427em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>8</span><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>25</span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class=mclose>)</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>18</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class=mclose>)</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style=top:-2.283335em;><span class=pstrut style=height:3.427em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>8</span><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>25</span><span class=mclose>)</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>109</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>±</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>3</span><span class="mord mathnormal" style=margin-right:0.03588em;>y</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.36033em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>8</span><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>25</span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class=mclose>)</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>109</span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>±</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>3</span><span class="mord mathnormal" style=margin-right:0.22222em;>Y</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord>.</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.379665em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>These are relevant because we can convert to points in projective space
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>=</mo><mi>P</mi><mi mathvariant=normal>/</mi><mi>R</mi><mo separator=true>,</mo><mi>q</mi><mo>=</mo><mi>Q</mi><mi mathvariant=normal>/</mi><mi>R</mi></mrow><annotation encoding="application/x-tex">p = P/R, q = Q/R</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal">Q</span><span class=mord>/</span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span></span></span></span> using <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo>=</mo><mn>8</mn><mo stretchy=false>(</mo><mn>3</mn><mi>X</mi><mo>−</mo><mn>25</mn><mi>Z</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">R = 8(3X - 25Z)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mord>8</span><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mord>25</span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class=mclose>)</span></span></span></span>:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mo fence=true>[</mo><mi>X</mi><mo>:</mo><mi>Y</mi><mo>:</mo><mi>Z</mi><mo fence=true>]</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mtext> </mtext><mo>⟺</mo><mtext> </mtext><mrow><mo fence=true>[</mo><mi>P</mi><mo>:</mo><mi>Q</mi><mo>:</mo><mi>R</mi><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>6</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mtext> </mtext><mo>⟺</mo><mtext> </mtext><mrow><mo fence=true>[</mo><mn>0</mn><mo>:</mo><mn>1</mn><mo>:</mo><mn>0</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>2</mn><msub><mi>P</mi><mn>1</mn></msub><mtext> or </mtext><mn>4</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mtext> </mtext><mo>⟺</mo><mtext> </mtext><mrow><mo fence=true>[</mo><mn>1</mn><mo>:</mo><mn>0</mn><mo>:</mo><mn>0</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>2</mn><msub><mi>P</mi><mn>1</mn></msub><mtext> or </mtext><mn>4</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mtext> </mtext><mo>⟺</mo><mtext> </mtext><mrow><mo fence=true>[</mo><mn>1</mn><mo>:</mo><mo>−</mo><mn>1</mn><mo>:</mo><mn>0</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><msub><mi>P</mi><mn>1</mn></msub><mtext> or </mtext><mn>5</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mtext> </mtext><mo>⟺</mo><mtext> </mtext><mrow><mo fence=true>[</mo><mn>1</mn><mo>:</mo><mn>1</mn><mo>:</mo><mn>1</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><msub><mi>P</mi><mn>1</mn></msub><mtext> or </mtext><mn>5</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mtext> </mtext><mo>⟺</mo><mtext> </mtext><mrow><mo fence=true>[</mo><mn>1</mn><mo>:</mo><mo>−</mo><mn>1</mn><mo>:</mo><mn>1</mn><mo fence=true>]</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mn>3</mn><msub><mi>P</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mtext> </mtext><mo>⟺</mo><mtext> </mtext><mrow><mo fence=true>[</mo><mo>−</mo><mn>1</mn><mo>:</mo><mn>1</mn><mo>:</mo><mn>1</mn><mo fence=true>]</mo></mrow><mi mathvariant=normal>.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}\left[ X : Y : Z \right] &\iff \left[ P : Q : R \right] \\ 6P_1 &\iff \left[ 0 : 1 : 0 \right] \\ 2P_1 \text{ or } 4P_1 &\iff \left[ 1 : 0 : 0 \right] \\ 2P_1 \text{ or } 4P_1 &\iff \left[ 1 : -1 : 0 \right] \\ P_1 \text{ or } 5P_1 &\iff \left[ 1 : 1 : 1 \right] \\ P_1 \text{ or } 5P_1 &\iff \left[ 1 : -1 : 1 \right] \\ 3P_1 &\iff \left[ -1 : 1 : 1 \right].\end{aligned}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:10.500000000000004em;vertical-align:-5.000000000000002em;></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:5.500000000000001em;><span style=top:-7.660000000000001em;><span class=pstrut style=height:3em;></span><span class=mord><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.22222em;>Y</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-6.16em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>6</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:-4.659999999999999em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class="mord text"><span class=mord> or </span></span><span class=mord>4</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:-3.1599999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class="mord text"><span class=mord> or </span></span><span class=mord>4</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:-1.6599999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class="mord text"><span class=mord> or </span></span><span class=mord>5</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:-0.15999999999999837em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class="mord text"><span class=mord> or </span></span><span class=mord>5</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span><span style=top:1.3400000000000016em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:5.000000000000002em;><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:5.500000000000001em;><span style=top:-7.660000000000001em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟺</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal">Q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-6.16em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟺</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>0</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>0</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-4.659999999999999em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟺</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>0</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>0</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-3.1599999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟺</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>−</span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>0</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-1.6599999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟺</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:-0.15999999999999837em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟺</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>−</span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span><span style=top:1.3400000000000016em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>⟺</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>−</span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>1</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>1</span><span class="mclose delimcenter" style=top:0em;>]</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:5.000000000000002em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>So unfortunately, half of the six rational points on the elliptic curve
correspond to points <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence=true>[</mo><mi>P</mi><mo>:</mo><mi>Q</mi><mo>:</mo><mi>R</mi><mo fence=true>]</mo></mrow><annotation encoding="application/x-tex">\left[ P : Q : R \right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal">Q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span></span> at infinity
and the other half are invalid because <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">p = 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span> or
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">q = 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span>.</p>
<h3 id=next-best-thing>The Next Best Thing</h3>
<p>So we can't find solutions over <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>Q</mi></mrow><annotation encoding="application/x-tex">\mathbf{Q}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8805499999999999em;vertical-align:-0.19444em;></span><span class="mord mathbf">Q</span></span></span></span> and it's pretty
obvious that we <strong>can</strong> find solutions over <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>R</mi></mrow><annotation encoding="application/x-tex">\mathbf{R}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68611em;vertical-align:0em;></span><span class="mord mathbf">R</span></span></span></span>
but is there anything simpler? What about over
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>Q</mi><mrow><mo fence=true>[</mo><msqrt><mi>n</mi></msqrt><mo fence=true>]</mo></mrow></mrow><annotation encoding="application/x-tex">\mathbf{Q}\left[\sqrt{n}\right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.05028em;vertical-align:-0.25em;></span><span class="mord mathbf">Q</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.8002800000000001em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class="mord mathnormal">n</span></span></span><span style=top:-2.76028em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.23972em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span></span> for a sufficiently
small value of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span></span></span></span>? Luckily, we can search for solutions
in these rings by slightly modifying our previous procedure to find
rational solutions to</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>n</mi><msup><mi>d</mi><mn>2</mn></msup><mo>=</mo><mi mathvariant=normal>Δ</mi></mrow><annotation encoding="application/x-tex">n d^2 = \Delta</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8641079999999999em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mord><span class="mord mathnormal">d</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class=mord>Δ</span></span></span></span></span>
</blockquote></div>
<p>and can use a family of Möbius transformations to transform to
Weierstrass form:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign=center columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mi>d</mi><mo>=</mo><mfrac><mrow><mn>63</mn><mi>n</mi><mi>y</mi></mrow><mrow><mo stretchy=false>(</mo><mn>3</mn><mi>n</mi><mi>x</mi><mo>−</mo><mn>25</mn><msup><mo stretchy=false>)</mo><mn>2</mn></msup></mrow></mfrac><mo separator=true>,</mo><mi>p</mi><mo>=</mo><mfrac><mrow><mn>9</mn><mo stretchy=false>(</mo><mi>n</mi><mi>x</mi><mo>+</mo><mn>1</mn><mo stretchy=false>)</mo></mrow><mrow><mn>4</mn><mo stretchy=false>(</mo><mn>3</mn><mi>n</mi><mi>x</mi><mo>−</mo><mn>25</mn><mo stretchy=false>)</mo></mrow></mfrac></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><msup><mi>y</mi><mn>2</mn></msup><mo>=</mo><msup><mi>x</mi><mn>3</mn></msup><mo>+</mo><mfrac><mn>215</mn><mrow><mn>3</mn><msup><mi>n</mi><mn>2</mn></msup></mrow></mfrac><mi>x</mi><mo>−</mo><mfrac><mn>10582</mn><mrow><mn>27</mn><msup><mi>n</mi><mn>3</mn></msup></mrow></mfrac><mi mathvariant=normal>.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{gather*}d = \frac{63ny}{(3nx - 25)^2}, p = \frac{9(nx + 1)}{4(3nx - 25)} \\ y^2 = x^3 + \frac{215}{3 n^2} x - \frac{10582}{27 n^3}.\end{gather*}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:4.97044em;vertical-align:-2.23522em;></span><span class=mord><span class=mtable><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.73522em;><span style=top:-4.73522em;><span class=pstrut style=height:3.427em;></span><span class=mord><span class="mord mathnormal">d</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal">n</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>25</span><span class=mclose><span class=mclose>)</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.740108em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>63</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style=margin-right:0.03588em;>y</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.427em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span><span class=mopen>(</span><span class=mord>3</span><span class="mord mathnormal">n</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>25</span><span class=mclose>)</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>9</span><span class=mopen>(</span><span class="mord mathnormal">n</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>1</span><span class=mclose>)</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style=top:-2.1777800000000003em;><span class=pstrut style=height:3.427em;></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em;>y</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord><span class="mord mathnormal">x</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.740108em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>215</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>27</span><span class=mord><span class="mord mathnormal">n</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.740108em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>10582</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord>.</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.23522em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>For all choices of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span></span></span></span> there is a rational point
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence=true>[</mo><mi>X</mi><mo>:</mo><mi>Y</mi><mo>:</mo><mi>Z</mi><mo fence=true>]</mo></mrow><mo>=</mo><mrow><mo fence=true>[</mo><mn>13</mn><mo>:</mo><mn>0</mn><mo>:</mo><mn>3</mn><mi>n</mi><mo fence=true>]</mo></mrow></mrow><annotation encoding="application/x-tex">\left[ X : Y : Z \right] = \left[ 13 : 0 : 3n \right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.22222em;>Y</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class="mclose delimcenter" style=top:0em;>]</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>13</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>0</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>3</span><span class="mord mathnormal">n</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span></span>
that will always have order two and will always correspond to the invalid
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>=</mo><mo>−</mo><mn>1</mn><mo separator=true>,</mo><mi>q</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">p = -1, q = 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8388800000000001em;vertical-align:-0.19444em;></span><span class=mord>−</span><span class=mord>1</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span>.</p>
<p>To find <strong>some</strong> solution over
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>Q</mi><mrow><mo fence=true>[</mo><msqrt><mi>n</mi></msqrt><mo fence=true>]</mo></mrow></mrow><annotation encoding="application/x-tex">\mathbf{Q}\left[\sqrt{n}\right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.05028em;vertical-align:-0.25em;></span><span class="mord mathbf">Q</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.8002800000000001em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class="mord mathnormal">n</span></span></span><span style=top:-2.76028em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.23972em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span></span> the "simplest" choice
would be <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">n = 2</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>2</span></span></span></span> but it turns out the elliptic curve produced
has even <strong>fewer</strong> rational points than the <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">n = 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span> case! The
rational points are isomorphic to <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>Z</mi><mi mathvariant=normal>/</mi><mn>2</mn><mi mathvariant=bold>Z</mi></mrow><annotation encoding="application/x-tex">\mathbf{Z}/2\mathbf{Z}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathbf">Z</span><span class=mord>/2</span><span class="mord mathbf">Z</span></span></span></span>
and they correspond to a point at infinity and the point
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>=</mo><mo>−</mo><mn>1</mn><mo separator=true>,</mo><mi>q</mi><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">p = -1, q = 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8388800000000001em;vertical-align:-0.19444em;></span><span class=mord>−</span><span class=mord>1</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span> common to all values of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span></span></span></span>.</p>
<p>The next choice up — <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">n = 3</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>3</span></span></span></span> — luckily yields
an infinite family of rational points! The group has the same generator with
finite order mentioned above and a second generator with infinite order
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence=true>[</mo><mi>X</mi><mo>:</mo><mi>Y</mi><mo>:</mo><mi>Z</mi><mo fence=true>]</mo></mrow><mo>=</mo><mrow><mo fence=true>[</mo><mn>31</mn><mo>:</mo><mn>66</mn><mo>:</mo><mn>9</mn><mo fence=true>]</mo></mrow></mrow><annotation encoding="application/x-tex">\left[ X : Y : Z \right] = \left[ 31 : 66 : 9 \right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class="mord mathnormal" style=margin-right:0.07847em;>X</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.22222em;>Y</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class="mord mathnormal" style=margin-right:0.07153em;>Z</span><span class="mclose delimcenter" style=top:0em;>]</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mord>31</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>66</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>:</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>9</span><span class="mclose delimcenter" style=top:0em;>]</span></span></span></span></span>.
Following our transformation backwards from this point we get</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>p</mi><mo>=</mo><mfrac><mn>17</mn><mn>4</mn></mfrac><mo separator=true>,</mo><mi>q</mi><mo>=</mo><mfrac><mrow><mo>−</mo><mn>13</mn><mo>±</mo><mn>11</mn><msqrt><mn>3</mn></msqrt></mrow><mn>8</mn></mfrac><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">p = \frac{17}{4}, q = \frac{-13 \pm 11 \sqrt{3}}{8}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal">p</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>17</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.27022em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.5842200000000002em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>8</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>−</span><span class=mord>13</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>±</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord>11</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.90722em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>3</span></span></span><span style=top:-2.86722em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.13278em;><span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>To clear denominators we can arbitrarily choose <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mo>=</mo><mn>8</mn></mrow><annotation encoding="application/x-tex">s = 8</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>8</span></span></span></span> and
find a solution to the original equation:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>a</mi><mo>=</mo><mn>34</mn><mo separator=true>,</mo><mi>b</mi><mo>=</mo><mo>−</mo><mn>13</mn><mo>+</mo><mn>11</mn><msqrt><mn>3</mn></msqrt><mo separator=true>,</mo><mi>c</mi><mo>=</mo><mo>−</mo><mn>13</mn><mo>−</mo><mn>11</mn><msqrt><mn>3</mn></msqrt><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">a = 34, b = -13 + 11 \sqrt{3}, c = -13 - 11 \sqrt{3}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">a</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8888799999999999em;vertical-align:-0.19444em;></span><span class=mord>34</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">b</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>−</span><span class=mord>13</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.150535em;vertical-align:-0.19444em;></span><span class=mord>11</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>3</span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mpunct>,</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class="mord mathnormal">c</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.72777em;vertical-align:-0.08333em;></span><span class=mord>−</span><span class=mord>13</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.04em;vertical-align:-0.08390500000000001em;></span><span class=mord>11</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.956095em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>3</span></span></span><span style=top:-2.916095em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.08390500000000001em;><span></span></span></span></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>It should come as no surprise that <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.69444em;vertical-align:0em;></span><span class="mord mathnormal">b</span></span></span></span> and
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi></mrow><annotation encoding="application/x-tex">c</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">c</span></span></span></span> are conjugates in
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>Q</mi><mrow><mo fence=true>[</mo><msqrt><mn>3</mn></msqrt><mo fence=true>]</mo></mrow></mrow><annotation encoding="application/x-tex">\mathbf{Q}\left[\sqrt{3}\right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.25723em;vertical-align:-0.35001em;></span><span class="mord mathbf">Q</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">[</span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.90722em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>3</span></span></span><span style=top:-2.86722em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.13278em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">]</span></span></span></span></span></span>.</p>
<h3 id=the-end>The End</h3>
<p>Even simple questions have deeper questions just one or two hops away! The
offhand comment by SyberMath spawned an exploration that led to much deeper
mathematics. In fact, the questions don't stop here. Clearly the differences
between <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>Q</mi><mrow><mo fence=true>[</mo><msqrt><mn>2</mn></msqrt><mo fence=true>]</mo></mrow></mrow><annotation encoding="application/x-tex">\mathbf{Q}\left[\sqrt{2}\right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.25723em;vertical-align:-0.35001em;></span><span class="mord mathbf">Q</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">[</span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.90722em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>2</span></span></span><span style=top:-2.86722em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.13278em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">]</span></span></span></span></span></span> and
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=bold>Q</mi><mrow><mo fence=true>[</mo><msqrt><mn>3</mn></msqrt><mo fence=true>]</mo></mrow></mrow><annotation encoding="application/x-tex">\mathbf{Q}\left[\sqrt{3}\right]</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.25723em;vertical-align:-0.35001em;></span><span class="mord mathbf">Q</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size1">[</span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.90722em;><span class=svg-align style=top:-3em;><span class=pstrut style=height:3em;></span><span class=mord style=padding-left:0.833em;><span class=mord>3</span></span></span><span style=top:-2.86722em;><span class=pstrut style=height:3em;></span><span class=hide-tail style=min-width:0.853em;height:1.08em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=1.08em viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.13278em;><span></span></span></span></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size1">]</span></span></span></span></span></span> above is part of a
larger pattern and investigating that pattern more could lead to even
more deep mathematics.</p>
<p>Given how simple the original homogeneous equation is, I was floored that there
are zero rational solutions. But I was also ecstatic that the tools exist to
conclusively confirm the absence of rational solutions. If you've made it this
far, thanks for following along!</p>
<hr style="margin-bottom: 25px; width: 50%;"><ol class=simple-footnotes><li id=sf-elementary-elliptic-1>I also really enjoy
<a href="https://www.youtube.com/c/MichaelPennMath/videos">Michael Penn</a> videos. <a href=#sf-elementary-elliptic-1-back class=simple-footnote-back>↩</a></li><li id=sf-elementary-elliptic-2>I actually consulted my great friend <a href="https://sites.google.com/a/alumni.brown.edu/whindes/home">Wade</a> when wading into these
deep waters. <a href=#sf-elementary-elliptic-2-back class=simple-footnote-back>↩</a></li><li id=sf-elementary-elliptic-3>I have swapped out the variable names used
in the video since I'll be introducing many more variables in this post. <a href=#sf-elementary-elliptic-3-back class=simple-footnote-back>↩</a></li></ol>Go Duration, PostgreSQL Interval2021-10-06T00:00:00-07:002021-10-06T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-10-06:/2021/10/go-duration-postgresql-interval.html<p>Building a web application in Go and using PostgreSQL as the database is a real
joy. Both of these tools are produced by incredibly vibrant open source
projects. These projects represent some of the best attributes of the open
source movement. When used in combination, occasionally idioms from Go don't …</p><p>Building a web application in Go and using PostgreSQL as the database is a real
joy. Both of these tools are produced by incredibly vibrant open source
projects. These projects represent some of the best attributes of the open
source movement. When used in combination, occasionally idioms from Go don't
translate to PostgreSQL and vice versa. Often this can be chalked up to the
object-relational impedance <a href="https://en.wikipedia.org/wiki/Object%E2%80%93relational_impedance_mismatch">mismatch</a>, but not always<sup id=sf-go-duration-postgresql-interval-1-back><a href=#sf-go-duration-postgresql-interval-1 class=simple-footnote title="Since a core design goal of Go is composition over inheritance, typical OOP patterns aren't that prevalant. As a result, object-relational impedance mismatch doesn't really rear its head very often.">1</a></sup>.</p>
<p>Recently, a <a href="https://twitter.com/perryfromsoma">teammate</a> and I bumped up against one of these rare situations
where the idioms don't line up. In Go, <code>time.Duration</code> is an integer, but
in PostgreSQL <code>INTERVAL</code> is essentially text from an application's perspective.</p>
<h3 id=go-details>Go Details</h3>
<p>The <code>time.Duration</code> standard library <a href="https://github.com/golang/go/blob/go1.17.1/src/time/time.go#L587-L590">type</a> is a 64-bit integer, with
associated methods tacked on via a type definition declaration:</p>
<div class=highlight><pre><span></span><code><span class=kd>type</span> <span class=nx>Duration</span> <span class=kt>int64</span>
</code></pre></div>
<p>This type can represent durations accurate to nanosecond precision, with
positive and negative extremes around 292 years.</p>
<h3 id=postgresql-details>PostgreSQL Details</h3>
<p>The PostgreSQL <code>INTERVAL</code> type is <a href="https://www.postgresql.org/docs/14/datatype-datetime.html">stored</a> as 128-bits internally and is
serialized as text over the wire in one of four <a href="https://www.postgresql.org/docs/14/datatype-datetime.html#INTERVAL-STYLE-OUTPUT-TABLE">output</a> formats.
It has less precision than a Go <code>time.Duration</code> (microseconds instead of
nanoseconds) but due to having twice as much space for storage, can support
much larger magnitudes: positive and negative extremes around 178,000,000
years.</p>
<h3 id=now-what>Now What?</h3>
<p>TL;DR using Go and PostgreSQL idioms simultaneously is beneficial, let's try
to make it work.</p>
<p>If the types are <strong>so</strong> different, what can we do? First of all, it's important
to understand the use case. The <strong>overwhelming</strong> majority of applications
are just fine with the lowest common denominator covered by both types:
microsecond precision and positive and negative extremes around 292 years.
For applications outside this majority, this is where you give up and roll
your own.</p>
<p>But even with this, why not just use a <code>string</code> in Go or use a <code>BIGINT</code> in
PostgreSQL<sup id=sf-go-duration-postgresql-interval-2-back><a href=#sf-go-duration-postgresql-interval-2 class=simple-footnote title="A PostgreSQL BIGINT exactly maps to int64 in Go.">2</a></sup>? A
<code>string</code> in Go would be pretty worthless for actual use beyond just telling
the database to do <strong>all</strong> of the business logic involving intervals. Using a
<code>BIGINT</code> in PostgreSQL similarly limits hinders the database. For example, an
<code>INTERVAL</code> allows sweeping for stale sessions in a PostgreSQL native way:</p>
<div class=highlight><pre><span></span><code><span class=c1>-- CREATE TABLE web_sessions (</span>
<span class=c1>-- id UUID NOT NULL,</span>
<span class=c1>-- email TEXT NOT NULL,</span>
<span class=c1>-- created_at TIMESTAMP WITH TIME ZONE NOT NULL,</span>
<span class=c1>-- updated_at TIMESTAMP WITH TIME ZONE NOT NULL,</span>
<span class=c1>-- max_age INTERVAL</span>
<span class=c1>-- )</span>
<span class=k>SELECT</span>
<span class=n>id</span><span class=p>,</span> <span class=n>email</span>
<span class=k>FROM</span>
<span class=n>web_sessions</span>
<span class=k>WHERE</span>
<span class=n>updated_at</span> <span class=o><</span> <span class=p>(</span><span class=n>NOW</span><span class=p>()</span> <span class=o>-</span> <span class=n>max_age</span><span class=p>)</span>
</code></pre></div>
<p>Conversion from <code>BIGINT</code> <strong>to</strong> <code>INTERVAL</code> can be done on the fly but this
breaks down for certain inputs:</p>
<div class=highlight><pre><span></span><code><span class=n>go_duration</span><span class=o>=></span> <span class=k>SELECT</span> <span class=k>EXTRACT</span><span class=p>(</span><span class=n>epoch</span> <span class=k>from</span> <span class=s1>'3 days 04:05:06'</span><span class=p>::</span><span class=nb>INTERVAL</span><span class=p>);</span>
<span class=n>date_part</span>
<span class=c1>-----------</span>
<span class=mi>273906</span>
<span class=p>(</span><span class=mi>1</span> <span class=k>row</span><span class=p>)</span>
<span class=n>go_duration</span><span class=o>=></span> <span class=k>SELECT</span> <span class=n>make_interval</span><span class=p>(</span><span class=n>secs</span> <span class=o>=></span> <span class=mi>273906</span><span class=p>);</span>
<span class=n>make_interval</span>
<span class=c1>---------------</span>
<span class=mi>76</span><span class=p>:</span><span class=mi>05</span><span class=p>:</span><span class=mi>06</span>
<span class=p>(</span><span class=mi>1</span> <span class=k>row</span><span class=p>)</span>
<span class=n>go_duration</span><span class=o>=></span> <span class=k>SELECT</span>
<span class=n>go_duration</span><span class=o>-></span> <span class=n>make_interval</span><span class=p>(</span><span class=n>days</span> <span class=o>=></span> <span class=mi>3</span><span class=p>,</span> <span class=n>hours</span> <span class=o>=></span> <span class=mi>4</span><span class=p>,</span> <span class=n>mins</span> <span class=o>=></span> <span class=mi>5</span><span class=p>,</span> <span class=n>secs</span> <span class=o>=></span> <span class=mi>6</span><span class=p>)</span> <span class=o>-</span>
<span class=n>go_duration</span><span class=o>-></span> <span class=n>make_interval</span><span class=p>(</span><span class=n>secs</span> <span class=o>=></span> <span class=mi>273906</span><span class=p>)</span> <span class=k>AS</span> <span class=n>delta</span><span class=p>;</span>
<span class=n>delta</span>
<span class=c1>------------------</span>
<span class=mi>3</span> <span class=n>days</span> <span class=o>-</span><span class=mi>72</span><span class=p>:</span><span class=mi>00</span><span class=p>:</span><span class=mi>00</span>
<span class=p>(</span><span class=mi>1</span> <span class=k>row</span><span class=p>)</span>
</code></pre></div>
<h3 id=making-go-do-the-work>Making Go Do the Work</h3>
<p>In cases like this — where the database wire representation differs from
the target value in Go — the Go standard library has our back. The
<code>sql.Scanner</code> <a href="https://github.com/golang/go/blob/go1.17.1/src/database/sql/sql.go#L395-L416">interface</a> allows custom transformation when reading data
in and the <code>driver.Valuer</code> <a href="https://github.com/golang/go/blob/go1.17.1/src/database/sql/driver/types.go#L35-L43">interface</a> allows custom transformation when
writing data out.</p>
<p>For example, assuming the active PostgreSQL session has <code>IntervalStyle</code> set
to <code>postgres</code>:</p>
<div class=highlight><pre><span></span><code><span class=kd>type</span> <span class=nx>DurationWrapped</span> <span class=kd>struct</span> <span class=p>{</span>
<span class=nx>time</span><span class=p>.</span><span class=nx>Duration</span>
<span class=p>}</span>
<span class=kd>func</span> <span class=p>(</span><span class=nx>dw</span> <span class=o>*</span><span class=nx>DurationWrapped</span><span class=p>)</span> <span class=nx>Scan</span><span class=p>(</span><span class=nx>src</span> <span class=kd>interface</span><span class=p>{})</span> <span class=kt>error</span> <span class=p>{</span>
<span class=k>if</span> <span class=nx>src</span> <span class=o>==</span> <span class=kc>nil</span> <span class=p>{</span>
<span class=nx>dw</span><span class=p>.</span><span class=nx>Duration</span> <span class=p>=</span> <span class=mi>0</span>
<span class=k>return</span> <span class=kc>nil</span>
<span class=p>}</span>
<span class=nx>srcStr</span><span class=p>,</span> <span class=nx>ok</span> <span class=o>:=</span> <span class=nx>src</span><span class=p>.(</span><span class=kt>string</span><span class=p>)</span>
<span class=k>if</span> <span class=p>!</span><span class=nx>ok</span> <span class=p>{</span>
<span class=k>return</span> <span class=nx>fmt</span><span class=p>.</span><span class=nx>Errorf</span><span class=p>(</span><span class=s>"duration column was not text; type %T"</span><span class=p>,</span> <span class=nx>src</span><span class=p>)</span>
<span class=p>}</span>
<span class=c1>// See: https://www.postgresql.org/docs/14/datatype-datetime.html</span>
<span class=c1>// IntervalStyle Output Table</span>
<span class=k>return</span> <span class=nx>unmarshalForIntervalStyle</span><span class=p>(</span><span class=nx>srcStr</span><span class=p>,</span> <span class=s>"postgres"</span><span class=p>,</span> <span class=o>&</span><span class=nx>dw</span><span class=p>.</span><span class=nx>Duration</span><span class=p>)</span>
<span class=p>}</span>
<span class=kd>func</span> <span class=p>(</span><span class=nx>dw</span> <span class=nx>DurationWrapped</span><span class=p>)</span> <span class=nx>Value</span><span class=p>()</span> <span class=p>(</span><span class=nx>driver</span><span class=p>.</span><span class=nx>Value</span><span class=p>,</span> <span class=kt>error</span><span class=p>)</span> <span class=p>{</span>
<span class=k>return</span> <span class=nx>marshalForIntervalStyle</span><span class=p>(</span><span class=nx>dw</span><span class=p>.</span><span class=nx>Duration</span><span class=p>,</span> <span class=s>"postgres"</span><span class=p>),</span> <span class=kc>nil</span>
<span class=p>}</span>
</code></pre></div>
<p>This approach works great in codebases where database calls directly interact
with <code>database/sql</code> primitives:</p>
<div class=highlight><pre><span></span><code><span class=nx>_</span><span class=p>,</span> <span class=nx>err</span> <span class=p>=</span> <span class=nx>pool</span><span class=p>.</span><span class=nx>ExecContext</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=s>"UPDATE ... max_age = $1"</span><span class=p>,</span> <span class=nx>dw</span><span class=p>)</span>
<span class=c1>// ...</span>
<span class=nx>rows</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>pool</span><span class=p>.</span><span class=nx>QueryContext</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=s>"SELECT ..."</span><span class=p>)</span>
<span class=c1>// ...</span>
<span class=nx>err</span> <span class=p>=</span> <span class=nx>rows</span><span class=p>.</span><span class=nx>Scan</span><span class=p>(</span><span class=o>&</span><span class=nx>session</span><span class=p>.</span><span class=nx>ID</span><span class=p>,</span> <span class=o>&</span><span class=nx>session</span><span class=p>.</span><span class=nx>Email</span><span class=p>,</span> <span class=o>&</span><span class=nx>session</span><span class=p>.</span><span class=nx>UpdatedAt</span><span class=p>,</span> <span class=o>&</span><span class=nx>dw</span><span class=p>)</span>
<span class=nx>session</span><span class=p>.</span><span class=nx>MaxAge</span> <span class=p>=</span> <span class=nx>dw</span><span class=p>.</span><span class=nx>Duration</span>
</code></pre></div>
<p>However, it's common for Go codebases to use a higher-level ORM or database
package that uses reflection to map database columns to fields in a Go struct.
For such codebases, it may be much more challenging (or even impossible) to
use a <code>DurationWrapped</code> value. It would be possible to just use a
<code>DurationWrapped</code> as the column type:</p>
<div class=highlight><pre><span></span><code><span class=kd>type</span> <span class=nx>Session</span> <span class=kd>struct</span> <span class=p>{</span>
<span class=nx>ID</span> <span class=nx>uuid</span><span class=p>.</span><span class=nx>UUID</span> <span class=s>`db:"id"`</span>
<span class=nx>Email</span> <span class=kt>string</span> <span class=s>`db:"email"`</span>
<span class=nx>CreatedAt</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Time</span> <span class=s>`db:"created_at"`</span>
<span class=nx>UpdatedAt</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Time</span> <span class=s>`db:"updated_at"`</span>
<span class=nx>MaxAge</span> <span class=nx>DurationWrapped</span> <span class=s>`db:"max_age"`</span>
<span class=p>}</span>
</code></pre></div>
<p>However, using a <code>DurationWrapped</code> instead of a <code>time.Duration</code> <strong>everywhere</strong>
the type is used is a large sacrifice. In my opinion, it is the tail wagging
the dog.</p>
<h3 id=making-postgresql-do-the-work>Making PostgreSQL Do the Work</h3>
<p>Instead of doing all the work in Go, we could instead invert the approach and
do all of the extra work in PostgreSQL. It's likely that most of this
conversion work will be more efficient (and possibly more correct) when done
in PostgreSQL vs. in our application code.</p>
<p>For example, when <strong>reading</strong>, convert to nanoseconds in the
database<sup id=sf-go-duration-postgresql-interval-3-back><a href=#sf-go-duration-postgresql-interval-3 class=simple-footnote title="The ::BIGINT conversion can go poorly for INTERVAL values that produce an epoch value too large to fit in an int64, but we are assuming our application doesn't need such values.">3</a></sup>:</p>
<div class=highlight><pre><span></span><code><span class=k>SELECT</span>
<span class=n>id</span><span class=p>,</span> <span class=n>email</span><span class=p>,</span> <span class=p>(</span><span class=k>EXTRACT</span><span class=p>(</span><span class=n>epoch</span> <span class=k>FROM</span> <span class=n>max_age</span><span class=p>)</span> <span class=o>*</span> <span class=mi>1000000000</span><span class=p>)::</span><span class=nb>BIGINT</span>
<span class=k>FROM</span>
<span class=n>web_sessions</span>
</code></pre></div>
<p>and when <strong>writing</strong>, make a best effort to convert from nanoseconds to
an <code>INTERVAL</code>:</p>
<div class=highlight><pre><span></span><code><span class=c1>-- -- NOTE: This is likely too simple.</span>
<span class=c1>-- CREATE OR REPLACE FUNCTION interval_from_nanoseconds(ns BIGINT)</span>
<span class=c1>-- RETURNS INTERVAL AS $$</span>
<span class=c1>-- SELECT make_interval(secs => ns::NUMERIC / 1000000000);</span>
<span class=c1>-- $$ LANGUAGE sql;</span>
<span class=k>UPDATE</span> <span class=n>web_sessions</span>
<span class=k>SET</span>
<span class=n>updated_at</span> <span class=o>=</span> <span class=n>NOW</span><span class=p>(),</span>
<span class=n>max_age</span> <span class=o>=</span> <span class=n>interval_from_nanoseconds</span><span class=p>(</span><span class=err>$</span><span class=mi>2</span><span class=p>)</span>
<span class=k>WHERE</span>
<span class=n>id</span> <span class=o>=</span> <span class=err>$</span><span class=mi>1</span>
</code></pre></div>
<h3 id=takeaways>Takeaways</h3>
<p>Clearly, the above approaches are filled with sharp corners and compromise.
However, the compromises above are likely acceptable for most applications
and the have the <strong>huge</strong> benefit of allowing usage of the Go and PostgreSQL
types that are "standard" for the task at hand.</p>
<p>The <code>time.Duration</code> and <code>INTERVAL</code> types are fundamentally designed for
different purposes — e.g. <code>'1 year 2 mons'::INTERVAL</code> always means "add a
year and a month" independent of the literal number of nanoseconds between the
two timestamps. In order to benefit from both of them, it's important to ensure
that usage both in Go and PostgreSQL aligns with the common set of
functionality shared by both types.</p>
<hr style="margin-bottom: 25px; width: 50%;"><ol class=simple-footnotes><li id=sf-go-duration-postgresql-interval-1>Since a core
design goal of Go is composition over inheritance, typical OOP patterns aren't
that prevalant. As a result, object-relational impedance mismatch doesn't
really rear its head very often. <a href=#sf-go-duration-postgresql-interval-1-back class=simple-footnote-back>↩</a></li><li id=sf-go-duration-postgresql-interval-2>A PostgreSQL <code>BIGINT</code> exactly maps to <code>int64</code> in Go. <a href=#sf-go-duration-postgresql-interval-2-back class=simple-footnote-back>↩</a></li><li id=sf-go-duration-postgresql-interval-3>The <code>::BIGINT</code> conversion can go poorly for <code>INTERVAL</code> values
that produce an epoch value too large to fit in an <code>int64</code>, but we are assuming
our application doesn't need such values. <a href=#sf-go-duration-postgresql-interval-3-back class=simple-footnote-back>↩</a></li></ol>Decrypting Vault Ciphertext with a Context2021-10-05T00:00:00-07:002021-10-05T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-10-05:/2021/10/decrypt-vault-ciphertext-context.html<p>In a previous <a href="/2021/07/vault-import.html">post</a>, I described a use case for customer provided keys
with Vault. One of the implications of this was the need for decryption after a
bulk data export. In that post, I gave a concrete example of decrypting Vault
ciphertext <strong>directly</strong> with a customer provided key. However …</p><p>In a previous <a href="/2021/07/vault-import.html">post</a>, I described a use case for customer provided keys
with Vault. One of the implications of this was the need for decryption after a
bulk data export. In that post, I gave a concrete example of decrypting Vault
ciphertext <strong>directly</strong> with a customer provided key. However, it's also
very common to encrypt using a derived key, created with a
<strong>user-supplied context</strong>. In this post, we'll give a concrete example of
generating a derived key and then decrypting Vault ciphertext with it.</p>
<h3 id="initialize">Initialize</h3>
<p>First, start a test Vault instance with transit encryption enabled:</p>
<div class="highlight"><pre><span></span><code>$ docker run \
> --rm \
> --detach \
> --name vault-dev-server \
> --publish 8200:8200 \
> --cap-add IPC_LOCK \
> --env VAULT_DEV_ROOT_TOKEN_ID=root \
> vault:1.8.3
$
$ export VAULT_TOKEN=root VAULT_ADDR=http://localhost:8200
$ vault secrets enable transit
Success! Enabled the transit secrets engine at: transit/
</code></pre></div>
<p>Then simulate a customer provided key and <strong>require</strong> that a user-supplied
context must always be used by setting <code>derived=true</code>:</p>
<div class="highlight"><pre><span></span><code>$ vault write transit/keys/acme-co-provided \
> type=aes256-gcm96 \
> allow_plaintext_backup=true \
> exportable=true \
> derived=true
Success! Data written to: transit/keys/acme-co-provided
</code></pre></div>
<h3 id="encrypt-data">Encrypt Data</h3>
<p>If we try to encrypt <strong>without</strong> a context, it will fail since key derivation
is required:</p>
<div class="highlight"><pre><span></span><code>$ echo -n 'FOO' | base64
Rk9P
$ vault write transit/encrypt/acme-co-provided plaintext=Rk9P
Error writing data to transit/encrypt/acme-co-provided: Error making API request.
URL: PUT http://localhost:8200/v1/transit/encrypt/acme-co-provided
Code: 400. Errors:
* missing 'context' for key derivation; the key was created using a derived
key, which means additional, per-request information must be included in order
to perform operations with the key
</code></pre></div>
<p>Instead, we encrypt the data with the context <code>{"bar":"baz"}</code>:</p>
<div class="highlight"><pre><span></span><code>$ echo -n '{"bar":"baz"}' | base64
eyJiYXIiOiJiYXoifQ==
$ vault write transit/encrypt/acme-co-provided plaintext=Rk9P context=eyJiYXIiOiJiYXoifQ==
Key Value
--- -----
ciphertext vault:v1:1pEqzFnkQEa5RA35ynhOd0Ye907S9PvWIq5dRPDP3Q==
key_version 1
</code></pre></div>
<h3 id="read-key-inputs">Read Key Inputs</h3>
<p>First, take note of the key derivation function used and the key type:</p>
<div class="highlight"><pre><span></span><code>$ vault read transit/keys/acme-co-provided
Key Value
--- -----
...
kdf hkdf_sha256
...
type aes256-gcm96
</code></pre></div>
<p>Then, export the key via the backup API:</p>
<div class="highlight"><pre><span></span><code>$ vault read transit/backup/acme-co-provided
Key Value
--- -----
backup eyJwb2xpY3kiOnsibmFtZS...
$
$ vault read --field=backup transit/backup/acme-co-provided | base64 --decode | jq
{
"policy": {
"name": "acme-co-provided",
"keys": {
"1": {
"key": "rph2pwTQCx+TD/lk+7o9igzQw5A7FU3+S+Z24Cf9Duk=",
...
}
},
...
},
...
}
</code></pre></div>
<h3 id="decrypt-ciphertext">Decrypt Ciphertext</h3>
<!-- Uses `cryptography@35.0.0` -->
<p>With the key, algorithms and ciphertext in hand, we are ready to decrypt.
First, create a derived key using the context:</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="kn">import</span> <span class="nn">cryptography.hazmat.primitives.hashes</span>
<span class="o">>>></span> <span class="n">algorithm</span> <span class="o">=</span> <span class="n">cryptography</span><span class="o">.</span><span class="n">hazmat</span><span class="o">.</span><span class="n">primitives</span><span class="o">.</span><span class="n">hashes</span><span class="o">.</span><span class="n">SHA256</span><span class="p">()</span>
<span class="o">>>></span>
<span class="o">>>></span> <span class="kn">import</span> <span class="nn">cryptography.hazmat.backends</span>
<span class="o">>>></span> <span class="n">backend</span> <span class="o">=</span> <span class="n">cryptography</span><span class="o">.</span><span class="n">hazmat</span><span class="o">.</span><span class="n">backends</span><span class="o">.</span><span class="n">default_backend</span><span class="p">()</span>
<span class="o">>>></span>
<span class="o">>>></span> <span class="kn">import</span> <span class="nn">base64</span>
<span class="o">>>></span> <span class="n">context</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64decode</span><span class="p">(</span><span class="sa">b</span><span class="s2">"eyJiYXIiOiJiYXoifQ=="</span><span class="p">)</span>
<span class="o">>>></span> <span class="n">context</span>
<span class="sa">b</span><span class="s1">'{"bar":"baz"}'</span>
<span class="o">>>></span>
<span class="o">>>></span> <span class="kn">import</span> <span class="nn">cryptography.hazmat.primitives.kdf.hkdf</span>
<span class="o">>>></span> <span class="n">hkdf</span> <span class="o">=</span> <span class="n">cryptography</span><span class="o">.</span><span class="n">hazmat</span><span class="o">.</span><span class="n">primitives</span><span class="o">.</span><span class="n">kdf</span><span class="o">.</span><span class="n">hkdf</span><span class="o">.</span><span class="n">HKDF</span><span class="p">(</span>
<span class="o">...</span> <span class="n">algorithm</span><span class="o">=</span><span class="n">algorithm</span><span class="p">,</span> <span class="n">length</span><span class="o">=</span><span class="mi">32</span><span class="p">,</span> <span class="n">info</span><span class="o">=</span><span class="n">context</span><span class="p">,</span> <span class="n">backend</span><span class="o">=</span><span class="n">backend</span><span class="p">,</span> <span class="n">salt</span><span class="o">=</span><span class="kc">None</span>
<span class="o">...</span> <span class="p">)</span>
<span class="o">>>></span>
<span class="o">>>></span> <span class="n">key</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64decode</span><span class="p">(</span><span class="s2">"rph2pwTQCx+TD/lk+7o9igzQw5A7FU3+S+Z24Cf9Duk="</span><span class="p">)</span>
<span class="o">>>></span> <span class="n">derived_key</span> <span class="o">=</span> <span class="n">hkdf</span><span class="o">.</span><span class="n">derive</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="o">>>></span> <span class="nb">len</span><span class="p">(</span><span class="n">derived_key</span><span class="p">)</span>
<span class="mi">32</span>
<span class="o">>>></span> <span class="n">derived_key</span>
<span class="sa">b</span><span class="s1">'uU</span><span class="se">\x18\xdf</span><span class="s1">...'</span>
</code></pre></div>
<p>Then, decrypt the ciphertext with the derived key:</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="n">encoded</span> <span class="o">=</span> <span class="s2">"1pEqzFnkQEa5RA35ynhOd0Ye907S9PvWIq5dRPDP3Q=="</span>
<span class="o">>>></span> <span class="n">iv_and_ciphertext</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64decode</span><span class="p">(</span><span class="n">encoded</span><span class="p">)</span>
<span class="o">>>></span> <span class="n">iv_bytes</span> <span class="o">=</span> <span class="n">iv_and_ciphertext</span><span class="p">[:</span><span class="mi">12</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">ciphertext_bytes</span> <span class="o">=</span> <span class="n">iv_and_ciphertext</span><span class="p">[</span><span class="mi">12</span><span class="p">:]</span>
<span class="o">>>></span>
<span class="o">>>></span> <span class="kn">import</span> <span class="nn">cryptography.hazmat.primitives.ciphers.aead</span>
<span class="o">>>></span> <span class="n">aead_cipher</span> <span class="o">=</span> <span class="n">cryptography</span><span class="o">.</span><span class="n">hazmat</span><span class="o">.</span><span class="n">primitives</span><span class="o">.</span><span class="n">ciphers</span><span class="o">.</span><span class="n">aead</span><span class="o">.</span><span class="n">AESGCM</span><span class="p">(</span><span class="n">derived_key</span><span class="p">)</span>
<span class="o">>>></span> <span class="n">aead_cipher</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">iv_bytes</span><span class="p">,</span> <span class="n">ciphertext_bytes</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="sa">b</span><span class="s1">'FOO'</span>
</code></pre></div>Atomically Idempotent2021-10-04T00:00:00-07:002021-10-04T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-10-04:/2021/10/atomically-idempotent.html<p>Recently, I was analyzing some initialization code in Go with a <a href="https://github.com/mat285">teammate</a>.
The value being initialized was meant to be used in concurrent Go, so
initialization had some requirement of atomicity. The code essentially boiled
down to:</p>
<div class="highlight"><pre><span></span><code><span class="kd">func</span> <span class="p">(</span><span class="nx">t</span> <span class="o">*</span><span class="nx">T</span><span class="p">)</span> <span class="nx">Start</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadInt32</span><span class="p">(</span><span class="o">&</span><span class="nx">t</span><span class="p">.</span><span class="nx">State</span><span class="p">)</span> <span class="o">==</span> <span class="nx">Started</span> <span class="p">{</span>
<span class="k">return</span> <span class="c1">// Early Exit …</span></code></pre></div><p>Recently, I was analyzing some initialization code in Go with a <a href="https://github.com/mat285">teammate</a>.
The value being initialized was meant to be used in concurrent Go, so
initialization had some requirement of atomicity. The code essentially boiled
down to:</p>
<div class="highlight"><pre><span></span><code><span class="kd">func</span> <span class="p">(</span><span class="nx">t</span> <span class="o">*</span><span class="nx">T</span><span class="p">)</span> <span class="nx">Start</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadInt32</span><span class="p">(</span><span class="o">&</span><span class="nx">t</span><span class="p">.</span><span class="nx">State</span><span class="p">)</span> <span class="o">==</span> <span class="nx">Started</span> <span class="p">{</span>
<span class="k">return</span> <span class="c1">// Early Exit</span>
<span class="p">}</span>
<span class="nx">atomic</span><span class="p">.</span><span class="nx">StoreInt32</span><span class="p">(</span><span class="o">&</span><span class="nx">t</span><span class="p">.</span><span class="nx">State</span><span class="p">,</span> <span class="nx">Started</span><span class="p">)</span>
<span class="nx">t</span><span class="p">.</span><span class="nx">Starting</span> <span class="o"><-</span> <span class="nx">Sentinel</span>
<span class="p">}</span>
</code></pre></div>
<p>However, we noted that this code is not truly atomic. The read and write of
the <code>State</code> value are individually atomic, but they are not atomic
<strong>together</strong>. One way to achieve atomicity here would be to just hold a mutex.
However, our discussion led to another way to avoid the mutex and to continue
to use the <code>int32</code> state value.</p>
<h3 id="atomicity-first">Atomicity First</h3>
<p>In order to ensure that our goroutine is the <strong>only</strong> one that can trigger
the sentinel event to the <code>Starting</code> channel, we need an atomic
compare-and-swap (CAS). This checks that our goroutine was the <strong>first</strong> to
attempt to set the state to <code>Started</code> and <strong>only then</strong> send the sentinel
value to the channel:</p>
<div class="highlight"><pre><span></span><code><span class="kd">func</span> <span class="p">(</span><span class="nx">t</span> <span class="o">*</span><span class="nx">T</span><span class="p">)</span> <span class="nx">Start</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">previous</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">LoadInt32</span><span class="p">(</span><span class="o">&</span><span class="nx">t</span><span class="p">.</span><span class="nx">State</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">previous</span> <span class="o">==</span> <span class="nx">Started</span> <span class="p">{</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="nx">swapped</span> <span class="o">:=</span> <span class="nx">atomic</span><span class="p">.</span><span class="nx">CompareAndSwapInt32</span><span class="p">(</span><span class="o">&</span><span class="nx">t</span><span class="p">.</span><span class="nx">State</span><span class="p">,</span> <span class="nx">previous</span><span class="p">,</span> <span class="nx">Started</span><span class="p">)</span>
<span class="k">if</span> <span class="p">!</span><span class="nx">swapped</span> <span class="p">{</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="nx">t</span><span class="p">.</span><span class="nx">Starting</span> <span class="o"><-</span> <span class="nx">Sentinel</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="idempotency-first">YMMV: Idempotent First</h3>
<p>Depending on the design goals of the code, the idempotency may be
a more crucial feature than the atomicity. For example, the code using a
<code>T</code> can be constructed in a way that sending <strong>multiple</strong> sentinel values to
the <code>Starting</code> channel is safely idempotent. In this case, a race between two
goroutines with the first code would not be problematic because they could
both send a sentinel.</p>Wrapping Behavior of context.WithValue()2021-09-10T00:00:00-07:002021-09-10T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-09-10:/2021/09/go-context-withvalue.html<h3>Motivation</h3>
<p>Throughout the Go monorepo we use <code>context.WithValue()</code> to "stash" a global
value on a root context. For example</p>
<div class="highlight"><pre><span></span><code><span class="nx">ctx</span> <span class="p">=</span> <span class="nx">logger</span><span class="p">.</span><span class="nx">WithLogger</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">log</span><span class="p">)</span>
<span class="c1">// ... later ...</span>
<span class="nx">log</span> <span class="o">:=</span> <span class="nx">logger</span><span class="p">.</span><span class="nx">GetLogger</span><span class="p">(</span><span class="nx">ctx</span><span class="p">)</span>
</code></pre></div>
<p>The implementations for stashing a <code>logger.Log</code> are in the same general form
as most context wrapping helpers:</p>
<div class="highlight"><pre><span></span><code><span class="kd">type</span> <span class="nx">loggerKey …</span></code></pre></div><h3>Motivation</h3>
<p>Throughout the Go monorepo we use <code>context.WithValue()</code> to "stash" a global
value on a root context. For example</p>
<div class="highlight"><pre><span></span><code><span class="nx">ctx</span> <span class="p">=</span> <span class="nx">logger</span><span class="p">.</span><span class="nx">WithLogger</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">log</span><span class="p">)</span>
<span class="c1">// ... later ...</span>
<span class="nx">log</span> <span class="o">:=</span> <span class="nx">logger</span><span class="p">.</span><span class="nx">GetLogger</span><span class="p">(</span><span class="nx">ctx</span><span class="p">)</span>
</code></pre></div>
<p>The implementations for stashing a <code>logger.Log</code> are in the same general form
as most context wrapping helpers:</p>
<div class="highlight"><pre><span></span><code><span class="kd">type</span> <span class="nx">loggerKey</span> <span class="kd">struct</span><span class="p">{}</span>
<span class="kd">func</span> <span class="nx">WithLogger</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span> <span class="nx">log</span> <span class="nx">Log</span><span class="p">)</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">context</span><span class="p">.</span><span class="nx">WithValue</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">loggerKey</span><span class="p">{},</span> <span class="nx">log</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nx">GetLogger</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">)</span> <span class="nx">Log</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">value</span> <span class="o">:=</span> <span class="nx">ctx</span><span class="p">.</span><span class="nx">Value</span><span class="p">(</span><span class="nx">loggerKey</span><span class="p">{});</span> <span class="nx">value</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">typed</span><span class="p">,</span> <span class="nx">ok</span> <span class="o">:=</span> <span class="nx">value</span><span class="p">.(</span><span class="nx">Log</span><span class="p">);</span> <span class="nx">ok</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">typed</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc">nil</span>
<span class="p">}</span>
</code></pre></div>
<p>Our goal here is to understand how <code>context.WithValue()</code> keeps the
data around and how <code>ctx.Value()</code> is able to extract it back out.</p>
<h3>Dealing with Unexported Types</h3>
<p>In addition, to defining the <code>context.Context</code> interface, the Go standard
library also defines some unexported concrete implementations. In particular,
<code>emptyCtx</code> is <a href="https://github.com/golang/go/blob/go1.17.1/src/context/context.go#L171">defined</a> to support <code>context.Background()</code> and <code>valueCtx</code>
is <a href="https://github.com/golang/go/blob/go1.17.1/src/context/context.go#L538">defined</a> to support <code>context.WithValue()</code>.</p>
<p>In order to see <strong>inside</strong> values of each of these types, we can create
a sufficiently similar type and then use the <code>reflect</code> and <code>unsafe</code> packages
to "cast" the memory from the standard library types into our own types.
For example:</p>
<div class="highlight"><pre><span></span><code><span class="kd">func</span> <span class="nx">CtxPointer</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">)</span> <span class="o">*</span><span class="kt">int</span> <span class="p">{</span>
<span class="nx">rc</span> <span class="o">:=</span> <span class="nx">reflect</span><span class="p">.</span><span class="nx">ValueOf</span><span class="p">(</span><span class="nx">ctx</span><span class="p">)</span>
<span class="nx">p</span> <span class="o">:=</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nx">Pointer</span><span class="p">(</span><span class="nx">rc</span><span class="p">.</span><span class="nx">Pointer</span><span class="p">())</span>
<span class="k">return</span> <span class="p">(</span><span class="o">*</span><span class="kt">int</span><span class="p">)(</span><span class="nx">p</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nx">ToEmptyCtx</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">)</span> <span class="o">*</span><span class="nx">EmptyCtx</span> <span class="p">{</span>
<span class="nx">p</span> <span class="o">:=</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nx">Pointer</span><span class="p">(</span><span class="nx">CtxPointer</span><span class="p">(</span><span class="nx">ctx</span><span class="p">))</span>
<span class="k">return</span> <span class="p">(</span><span class="o">*</span><span class="nx">EmptyCtx</span><span class="p">)(</span><span class="nx">p</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>The fields in the types themselves are straightforward to copy over:</p>
<div class="highlight"><pre><span></span><code><span class="kd">type</span> <span class="nx">EmptyCtx</span> <span class="kt">int</span>
<span class="kd">type</span> <span class="nx">ValueCtx</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="nx">wrapped</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span> <span class="c1">// Intentionally avoid struct-embedding</span>
<span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="kd">interface</span><span class="p">{}</span>
<span class="p">}</span>
</code></pre></div>
<h3>Unwrapping It All</h3>
<p>In order to better understand how context wrapping via <code>context.WithValue()</code>
works, we'll stash multiple values for the same key onto a context:</p>
<div class="highlight"><pre><span></span><code><span class="kd">type</span> <span class="nx">simpleKey</span> <span class="kd">struct</span><span class="p">{}</span>
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">ctx1</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Background</span><span class="p">()</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">"ctx1 = %s\n"</span><span class="p">,</span> <span class="nx">ToEmptyCtx</span><span class="p">(</span><span class="nx">ctx1</span><span class="p">))</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">" ctx1.Value(simpleKey{}) = %v\n"</span><span class="p">,</span> <span class="nx">ctx1</span><span class="p">.</span><span class="nx">Value</span><span class="p">(</span><span class="nx">simpleKey</span><span class="p">{}))</span>
<span class="c1">// Wrap once.</span>
<span class="nx">ctx2</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nx">WithValue</span><span class="p">(</span><span class="nx">ctx1</span><span class="p">,</span> <span class="nx">simpleKey</span><span class="p">{},</span> <span class="s">"x"</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">"ctx2 = %s\n"</span><span class="p">,</span> <span class="nx">ToValueCtx</span><span class="p">(</span><span class="nx">ctx2</span><span class="p">))</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">" ctx2.Value(simpleKey{}) = %q\n"</span><span class="p">,</span> <span class="nx">ctx2</span><span class="p">.</span><span class="nx">Value</span><span class="p">(</span><span class="nx">simpleKey</span><span class="p">{}))</span>
<span class="c1">// Wrap twice.</span>
<span class="nx">ctx3</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nx">WithValue</span><span class="p">(</span><span class="nx">ctx2</span><span class="p">,</span> <span class="nx">simpleKey</span><span class="p">{},</span> <span class="s">"y"</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">"ctx3 = %s\n"</span><span class="p">,</span> <span class="nx">ToValueCtx</span><span class="p">(</span><span class="nx">ctx3</span><span class="p">))</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">" ctx3.Value(simpleKey{}) = %q\n"</span><span class="p">,</span> <span class="nx">ctx3</span><span class="p">.</span><span class="nx">Value</span><span class="p">(</span><span class="nx">simpleKey</span><span class="p">{}))</span>
<span class="c1">// Wrap thrice.</span>
<span class="nx">ctx4</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nx">WithValue</span><span class="p">(</span><span class="nx">ctx3</span><span class="p">,</span> <span class="nx">simpleKey</span><span class="p">{},</span> <span class="s">"z"</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">"ctx4 = %s\n"</span><span class="p">,</span> <span class="nx">ToValueCtx</span><span class="p">(</span><span class="nx">ctx4</span><span class="p">))</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">" ctx4.Value(simpleKey{}) = %q\n"</span><span class="p">,</span> <span class="nx">ctx4</span><span class="p">.</span><span class="nx">Value</span><span class="p">(</span><span class="nx">simpleKey</span><span class="p">{}))</span>
<span class="p">}</span>
</code></pre></div>
<p>Running the script we see that the <strong>latest</strong> value stashed for the key
wins in <code>valueCtx.Value()</code>. We also see that the second stage (<code>ctx2</code>)
wraps the first (<code>0xc00009e000</code>), the third stage (<code>ctx3</code>) wraps the second
(<code>0xc0000981b0</code>) and so on.</p>
<div class="highlight"><pre><span></span><code>$ go run docs/go-context-withvalue/main.go
ctx1 = EmptyCtx(0) [address=0xc00009e000]
ctx1.Value(simpleKey{}) = <nil>
ctx2 = ValueCtx(wrapped=0xc00009e000, key=main.simpleKey{}, val="x") [address=0xc0000981b0]
ctx2.Value(simpleKey{}) = "x"
ctx3 = ValueCtx(wrapped=0xc0000981b0, key=main.simpleKey{}, val="y") [address=0xc0000981e0]
ctx3.Value(simpleKey{}) = "y"
ctx4 = ValueCtx(wrapped=0xc0000981e0, key=main.simpleKey{}, val="z") [address=0xc000098210]
ctx4.Value(simpleKey{}) = "z"
</code></pre></div>Setting Per-Connection Timeouts with TypeORM2021-08-24T00:00:00-07:002021-08-24T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-08-24:/2021/08/typeorm-timeouts.html<h3>PostgreSQL Statement Timeout</h3>
<p>For <strong>most</strong> applications that use a database, user-facing queries <strong>must</strong>
complete in a reasonable amount of time. In order to ensure a maximum
query time, PostgreSQL supports a <code>statement_timeout</code> which will cause a
query to be cancelled if it exceeds the timeout:</p>
<div class="highlight"><pre><span></span><code>$ psql
monsters_inc=> SHOW statement_timeout;
statement_timeout …</code></pre></div><h3>PostgreSQL Statement Timeout</h3>
<p>For <strong>most</strong> applications that use a database, user-facing queries <strong>must</strong>
complete in a reasonable amount of time. In order to ensure a maximum
query time, PostgreSQL supports a <code>statement_timeout</code> which will cause a
query to be cancelled if it exceeds the timeout:</p>
<div class="highlight"><pre><span></span><code>$ psql
monsters_inc=> SHOW statement_timeout;
statement_timeout
-------------------
5s
(1 row)
monsters_inc=> SELECT pg_sleep(6);
ERROR: canceling statement due to statement timeout
</code></pre></div>
<p>This value can be set on an existing connection or can be set
<strong>globally</strong> for a user:</p>
<div class="highlight"><pre><span></span><code>$ psql
<span class="nv">monsters_inc</span><span class="o">=</span>> ALTER ROLE sully SET <span class="nv">statement_timeout</span> <span class="o">=</span> <span class="s1">'6s'</span><span class="p">;</span>
ALTER ROLE
<span class="nv">monsters_inc</span><span class="o">=</span>> SHOW statement_timeout<span class="p">;</span>
statement_timeout
-------------------
<span class="m">0</span>
<span class="o">(</span><span class="m">1</span> row<span class="o">)</span>
<span class="nv">monsters_inc</span><span class="o">=</span>> <span class="se">\q</span>
$
$ <span class="c1"># Open new connection so default can take effect</span>
$ psql
<span class="nv">monsters_inc</span><span class="o">=</span>> SHOW statement_timeout<span class="p">;</span>
statement_timeout
-------------------
6s
<span class="o">(</span><span class="m">1</span> row<span class="o">)</span>
<span class="nv">monsters_inc</span><span class="o">=</span>> <span class="se">\q</span>
$
$ <span class="c1"># Connection-level override</span>
$ <span class="nv">PGOPTIONS</span><span class="o">=</span><span class="s2">"-c statement_timeout=4s"</span> psql
<span class="nv">monsters_inc</span><span class="o">=</span>> SHOW statement_timeout<span class="p">;</span>
statement_timeout
-------------------
4s
<span class="o">(</span><span class="m">1</span> row<span class="o">)</span>
<span class="nv">monsters_inc</span><span class="o">=</span>> <span class="se">\q</span>
</code></pre></div>
<h3>Motivation</h3>
<p>Setting a <strong>global</strong> statement timeout for a user <strong>can</strong> be a helpful
feature, but often is too much of a blunt object. For example, some types
of queries (e.g. migrations) may require a different timeout on a temporary
basis. Having the ability to use a connection-level timeout that <strong>differs</strong>
from a common / global one is likely a need that will come up during the
application development lifecycle.</p>
<p>Another common use case here is the need for two distinct "long running query"
and "user facing query" connection pools for the same application user.
Those two pools need different statement timeouts (given the types of queries)
so can't rely on a single global setting.</p>
<h3>Configuring TypeORM</h3>
<p>Unfortunately, TypeORM tries to cover <strong>many</strong> database engines beyond
just PostgreSQL. As a result, there is no explicit TypeORM support for most
PostgreSQL run-time parameters. This is because these are specific to
PostgreSQL and don't generalize well to other support databases like MySQL.</p>
<p>A general purpose way of passing along any run-time parameter (e.g.
<code>statement_timeout</code> or <code>search_path</code> to specify a PostgreSQL schema) is to
use the <code>extra.options</code> field in the TypeORM connection options.</p>
<div class="highlight"><pre><span></span><code><span class="k">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">typeorm</span> <span class="k">from</span> <span class="s2">"typeorm"</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">OPTIONS</span>: <span class="kt">typeorm.ConnectionOptions</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">name</span><span class="o">:</span> <span class="s2">"default"</span><span class="p">,</span>
<span class="kd">type</span><span class="o">:</span> <span class="s2">"postgres"</span><span class="p">,</span>
<span class="nx">host</span><span class="o">:</span> <span class="s2">"pg-shared.chimera.us-unicorn-3.rds.amazonaws.com"</span><span class="p">,</span>
<span class="nx">port</span><span class="o">:</span> <span class="s2">"5432"</span><span class="p">,</span>
<span class="nx">database</span><span class="o">:</span> <span class="s2">"monsters_inc"</span><span class="p">,</span>
<span class="nx">username</span><span class="o">:</span> <span class="s2">"sully"</span><span class="p">,</span>
<span class="nx">password</span><span class="o">:</span> <span class="s2">"s33krit"</span><span class="p">,</span>
<span class="nx">extra</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">options</span><span class="o">:</span> <span class="s2">"-c statement_timeout=5500ms -c search_path=monsters"</span><span class="p">,</span>
<span class="p">},</span>
<span class="nx">entities</span><span class="o">:</span> <span class="p">[</span><span class="s2">"..."</span><span class="p">],</span>
<span class="nx">migrations</span><span class="o">:</span> <span class="p">[</span><span class="s2">"..."</span><span class="p">],</span>
<span class="p">};</span>
</code></pre></div>
<h3>References</h3>
<ul>
<li>GitHub issue <a href="https://github.com/typeorm/typeorm/issues/3929#issuecomment-736096616">discussion</a> on <code>node-postgres</code> about setting named
run-time parameters (e.g. <code>statement_timeout</code>)</li>
<li>GitHub issue <a href="https://github.com/brianc/node-postgres/issues/983#issuecomment-736075608">discussion</a> on <code>typeorm</code> about setting <code>lock_timeout</code></li>
</ul>
<blockquote>
<p><strong>Caveat Emptor</strong>: While I am describing a technique to improve the usage of
TypeORM, this is not an endorsement of TypeORM or ORMs in general. I wrote
this to address internal usage at Blend.</p>
</blockquote>Importing External Keys into Vault2021-07-09T00:00:00-07:002021-07-09T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-07-09:/2021/07/vault-import.html<p><img alt=Vault src="/images/Vault_PrimaryLogo_Black_RGB.png"></p>
<h3>Contents</h3>
<ul>
<li><a href=#motivation>Motivation</a></li>
<li><a href=#importing-via-restore>"Importing" via Restore</a></li>
<li><a href=#decrypting-exported-ciphertext>Decrypting Exported Ciphertext</a></li>
<li><a href=#key-backup-format>Key Backup Format</a></li>
</ul>
<h3 id=motivation>Motivation</h3>
<p>To understand why it's helpful to import external keys into Vault, it's
important to understand</p>
<ul>
<li>How and why encrypted data is stored in databases</li>
<li>How Vault provides features that aid in encrypting and decrypting data</li>
<li>Reasons for data …</li></ul><p><img alt=Vault src="/images/Vault_PrimaryLogo_Black_RGB.png"></p>
<h3>Contents</h3>
<ul>
<li><a href=#motivation>Motivation</a></li>
<li><a href=#importing-via-restore>"Importing" via Restore</a></li>
<li><a href=#decrypting-exported-ciphertext>Decrypting Exported Ciphertext</a></li>
<li><a href=#key-backup-format>Key Backup Format</a></li>
</ul>
<h3 id=motivation>Motivation</h3>
<p>To understand why it's helpful to import external keys into Vault, it's
important to understand</p>
<ul>
<li>How and why encrypted data is stored in databases</li>
<li>How Vault provides features that aid in encrypting and decrypting data</li>
<li>Reasons for data export and potential consumers of exported data</li>
</ul>
<p>When storing PII and other sensitive information in a database, a common
best practice is to first <strong>encrypt</strong> the data before storing it.
For example, in a <code>users</code> table in an RDBMS, the social security number
(<code>ssn</code>) is sensitive but other columns can be stored in cleartext. Encryption
can be done with homegrown schemes that utilize a (very sensitive) primary key
on a per-application basis. However, this doesn't scale well in medium to
large companies where there are <strong>many</strong> databases and applications, all with
a similar need.</p>
<p>This is where HashiCorp <a href="https://www.vaultproject.io/">Vault</a> comes in. With a single instance of Vault,
an entire organization can utilize a centralized store for secrets and
an interface for encrypting and decrypting data. Access to these features can
be tightly controlled via the use of policies, e.g. if two applications want to
share access to the same secrets or encryption keys. A core design
consideration for Vault is that all keys used for encryption remain
"contained" within. Key export is <strong>possible</strong> but must be explicitly opted
into.</p>
<p>The last piece of the puzzle here is data export. In multitenant architectures,
data is often divided by customer via logical or physical segmentation. A given
customer may want an export of their data, e.g. for performing an
audit. In a <strong>raw</strong> database dump of the customer's data, all of the sensitive
fields (stored as ciphertext) would be essentially missing. If the data size is
large enough, manually decrypting <strong>every</strong> piece of sensitive data may take
too long or put too large of a strain on Vault to be worth it. This is where
the demand for a <strong>customer provided key</strong> comes in. If the customer already
owns the root key used to encrypt their data, then ciphertext in a raw dump
could be decrypted <strong>after</strong> a data export.</p>
<h3 id=importing-via-restore>"Importing" via Restore</h3>
<p>There is no <strong>official</strong> way to import external keys into Vault, but this
feature can be approximated. Vault provides a backup and restore mechanism on
a per-key basis and this can be used to "restore" a synthetic backup
constructed from a customer provided key<sup id=sf-vault-import-1-back><a href=#sf-vault-import-1 class=simple-footnote title="It should be noted that this goes against one of the design considerations of Vault, i.e. that keys are generated internally and are never exposed outside of Vault.">1</a></sup>.</p>
<p>As an example here, a synthetic backup of an <code>aes256-gcm96</code> key will be
created. See <a href=#key-backup-format>Key Backup Format</a> for more details on how
to construct a synthetic backup. This means 32 bytes<sup id=sf-vault-import-2-back><a href=#sf-vault-import-2 class=simple-footnote title="The secret key is 32 bytes (or 256 bits) since the scheme used is aes256-gcm96.">2</a></sup> are
needed for the key, base64 encoded for JSON:</p>
<div class=highlight><pre><span></span><code><span class=p>{</span>
<span class=nt>"policy"</span><span class=p>:</span> <span class=p>{</span>
<span class=nt>"name"</span><span class=p>:</span> <span class=s2>"acme-co-provided"</span><span class=p>,</span>
<span class=nt>"type"</span><span class=p>:</span> <span class=mi>0</span><span class=p>,</span>
<span class=nt>"keys"</span><span class=p>:</span> <span class=p>{</span>
<span class=nt>"1"</span><span class=p>:</span> <span class=p>{</span>
<span class=nt>"key"</span><span class=p>:</span> <span class=s2>"MoUxGpXXLY1GpicsJG4FFCSp/t6HzVVlddS+CIbEJyE="</span><span class=p>,</span>
<span class=nt>"hmac_key"</span><span class=p>:</span> <span class=kc>null</span><span class=p>,</span>
<span class=nt>"time"</span><span class=p>:</span> <span class=s2>"2021-07-08T18:21:51.080371000Z"</span><span class=p>,</span>
<span class=err>//</span> <span class=err>...</span>
<span class=p>}</span>
<span class=p>},</span>
<span class=err>//</span> <span class=err>...</span>
<span class=p>}</span>
<span class=p>}</span>
</code></pre></div>
<p>Once the backup is constructed, the <a href="https://www.vaultproject.io/api/secret/transit#restore-key">restore</a> API should be used with
the backup as a base64 encoded field:</p>
<div class=highlight><pre><span></span><code>$ BACKUP_B64="$(cat backup.json | base64)"
$ vault write transit/restore/acme-co-provided backup="${BACKUP_B64}"
Success! Data written to: transit/restore/acme-co-provided
</code></pre></div>
<h3 id=decrypting-exported-ciphertext>Decrypting Exported Ciphertext</h3>
<p>For a given party with a <strong>known</strong> key, decrypting ciphertext outside of Vault
is the primary goal of providing an external key. As an example, consider
the ciphertext produced when encrypting the secret text <code>FOO</code>:</p>
<div class=highlight><pre><span></span><code>$ echo -n FOO | base64
Rk9P
$
$ vault write transit/encrypt/acme-co-provided plaintext=Rk9P
Key Value
--- -----
ciphertext vault:v1:aMEvW33l8iXqoDcvXl8KTtkaJEVcB8yeSsQ69mOltw==
key_version 1
</code></pre></div>
<p>The encrypted content comes after the header <code>vault:v1:</code>, which in this
case is 31 bytes base64 encoded. Of these, the <a href="https://discuss.hashicorp.com/t/what-is-the-vault-ciphertext-format-in-case-i-want-to-parse-it/3574/2">first 12</a> bytes<sup id=sf-vault-import-3-back><a href=#sf-vault-import-3 class=simple-footnote title="The IV is 12 bytes (or 96 bits) since the scheme used is aes256-gcm96.">3</a></sup>
are the initialization vector (IV):</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>encoded</span> <span class=o>=</span> <span class=s2>"aMEvW33l8iXqoDcvXl8KTtkaJEVcB8yeSsQ69mOltw=="</span>
<span class=o>>>></span>
<span class=o>>>></span> <span class=kn>import</span> <span class=nn>base64</span>
<span class=o>>>></span> <span class=n>iv_and_ciphertext</span> <span class=o>=</span> <span class=n>base64</span><span class=o>.</span><span class=n>b64decode</span><span class=p>(</span><span class=n>encoded</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>iv_bytes</span> <span class=o>=</span> <span class=n>iv_and_ciphertext</span><span class=p>[:</span><span class=mi>12</span><span class=p>]</span>
<span class=o>>>></span> <span class=n>ciphertext_bytes</span> <span class=o>=</span> <span class=n>iv_and_ciphertext</span><span class=p>[</span><span class=mi>12</span><span class=p>:]</span>
</code></pre></div>
<p>Using the key from <code>backup.json</code> and the excellent Python <code>cryptopgraphy</code>
<a href="https://cryptography.io/en/latest/">package</a>, this ciphertext can be decomposed and decrypted:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>key_bytes</span> <span class=o>=</span> <span class=n>base64</span><span class=o>.</span><span class=n>b64decode</span><span class=p>(</span><span class=s2>"MoUxGpXXLY1GpicsJG4FFCSp/t6HzVVlddS+CIbEJyE="</span><span class=p>)</span>
<span class=o>>>></span>
<span class=o>>>></span> <span class=kn>import</span> <span class=nn>cryptography.hazmat.primitives.ciphers.aead</span>
<span class=o>>>></span> <span class=n>aead_cipher</span> <span class=o>=</span> <span class=n>cryptography</span><span class=o>.</span><span class=n>hazmat</span><span class=o>.</span><span class=n>primitives</span><span class=o>.</span><span class=n>ciphers</span><span class=o>.</span><span class=n>aead</span><span class=o>.</span><span class=n>AESGCM</span><span class=p>(</span><span class=n>key_bytes</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>aead_cipher</span><span class=o>.</span><span class=n>decrypt</span><span class=p>(</span><span class=n>iv_bytes</span><span class=p>,</span> <span class=n>ciphertext_bytes</span><span class=p>,</span> <span class=kc>None</span><span class=p>)</span>
<span class=sa>b</span><span class=s1>'FOO'</span>
</code></pre></div>
<p>For larger ciphertext (e.g. for an encrypted PDF file), it may be desired to
do streaming decryption instead of using <code>aead.AESGCM</code>. In this case, it's
crucial to know that the <strong>last</strong> 16 bytes are the authentication tag:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=kn>import</span> <span class=nn>cryptography.hazmat.primitives.ciphers.algorithms</span>
<span class=o>>>></span> <span class=n>algorithm</span> <span class=o>=</span> <span class=n>cryptography</span><span class=o>.</span><span class=n>hazmat</span><span class=o>.</span><span class=n>primitives</span><span class=o>.</span><span class=n>ciphers</span><span class=o>.</span><span class=n>algorithms</span><span class=o>.</span><span class=n>AES</span><span class=p>(</span><span class=n>key_bytes</span><span class=p>)</span>
<span class=o>>>></span>
<span class=o>>>></span> <span class=kn>import</span> <span class=nn>cryptography.hazmat.primitives.ciphers.modes</span>
<span class=o>>>></span> <span class=n>tag</span> <span class=o>=</span> <span class=n>ciphertext_bytes</span><span class=p>[</span><span class=o>-</span><span class=mi>16</span><span class=p>:]</span>
<span class=o>>>></span> <span class=n>mode</span> <span class=o>=</span> <span class=n>cryptography</span><span class=o>.</span><span class=n>hazmat</span><span class=o>.</span><span class=n>primitives</span><span class=o>.</span><span class=n>ciphers</span><span class=o>.</span><span class=n>modes</span><span class=o>.</span><span class=n>GCM</span><span class=p>(</span><span class=n>iv_bytes</span><span class=p>,</span> <span class=n>tag</span><span class=o>=</span><span class=n>tag</span><span class=p>)</span>
<span class=o>>>></span>
<span class=o>>>></span> <span class=kn>import</span> <span class=nn>cryptography.hazmat.primitives.ciphers</span>
<span class=o>>>></span> <span class=n>cipher</span> <span class=o>=</span> <span class=n>cryptography</span><span class=o>.</span><span class=n>hazmat</span><span class=o>.</span><span class=n>primitives</span><span class=o>.</span><span class=n>ciphers</span><span class=o>.</span><span class=n>Cipher</span><span class=p>(</span><span class=n>algorithm</span><span class=p>,</span> <span class=n>mode</span><span class=o>=</span><span class=n>mode</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>decryptor</span> <span class=o>=</span> <span class=n>cipher</span><span class=o>.</span><span class=n>decryptor</span><span class=p>()</span>
<span class=o>>>></span> <span class=n>decryptor</span><span class=o>.</span><span class=n>update</span><span class=p>(</span><span class=n>ciphertext_bytes</span><span class=p>[:</span><span class=o>-</span><span class=mi>16</span><span class=p>])</span> <span class=c1># Do not include `tag`</span>
<span class=sa>b</span><span class=s1>'FOO'</span>
<span class=o>>>></span> <span class=n>decryptor</span><span class=o>.</span><span class=n>finalize</span><span class=p>()</span>
<span class=sa>b</span><span class=s1>''</span>
</code></pre></div>
<h3 id=key-backup-format>Key Backup Format</h3>
<p>To construct a synthetic backup, it's necessary to understand the format of
the backup JSON. To inspect an existing one, create an exportable key:</p>
<div class=highlight><pre><span></span><code>$ vault write transit/keys/acme-co-provided \
> type=aes256-gcm96 allow_plaintext_backup=true exportable=true
Success! Data written to: transit/keys/acme-co-provided
$
$ vault read transit/keys/acme-co-provided
Key Value
--- -----
allow_plaintext_backup true
deletion_allowed false
derived false
exportable true
keys map[1:1625786511]
latest_version 1
min_available_version 0
min_decryption_version 1
min_encryption_version 0
name acme-co-provided
supports_decryption true
supports_derivation true
supports_encryption true
supports_signing false
type aes256-gcm96
</code></pre></div>
<p>and then export the key:</p>
<div class=highlight><pre><span></span><code>$ vault read transit/backup/acme-co-provided
Key Value
--- -----
backup eyJwb2xp...
</code></pre></div>
<p>Once exported, the <code>backup</code> value can be base64 decoded and will resemble
the JSON snippet <a href=#importing-via-restore>above</a>. For more details on the
fields, see the underyling Go <a href="https://github.com/hashicorp/vault/blob/v1.7.3/sdk/helper/keysutil/policy.go#L302">struct</a>.</p><ol class=simple-footnotes><li id=sf-vault-import-1>It should be noted that
this goes <strong>against</strong> one of the design considerations of Vault, i.e.
that keys are generated internally and are never exposed outside of
Vault. <a href=#sf-vault-import-1-back class=simple-footnote-back>↩</a></li><li id=sf-vault-import-2>The secret key is
32 bytes (or 256 bits) since the scheme used is <code>aes256-gcm96</code>. <a href=#sf-vault-import-2-back class=simple-footnote-back>↩</a></li><li id=sf-vault-import-3>The IV
is 12 bytes (or 96 bits) since the scheme used is <code>aes256-gcm96</code>. <a href=#sf-vault-import-3-back class=simple-footnote-back>↩</a></li></ol>Fixing the Custom CA Problem in Node.js2021-05-12T00:00:00-07:002021-05-12T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-05-12:/2021/05/node-ca-append.html<blockquote>
<p><strong>TL;DR</strong>: Using the <code>ca</code> field to specify custom CAs (certificate
authorities) in Node.js is a <a href="/2021/05/node-ca-footgun.html">footgun</a>. It replaces (rather than appends
to) the root trust store which can lead to unintended consequences. I've
seen this behavior cause outages in production when a third party server does
a routine …</p></blockquote><blockquote>
<p><strong>TL;DR</strong>: Using the <code>ca</code> field to specify custom CAs (certificate
authorities) in Node.js is a <a href="/2021/05/node-ca-footgun.html">footgun</a>. It replaces (rather than appends
to) the root trust store which can lead to unintended consequences. I've
seen this behavior cause outages in production when a third party server does
a routine certificate rotation.</p>
<p>By using the <code>ca-append</code> <a href="https://www.npmjs.com/package/ca-append">package</a>, the built-in handling in
Node.js will be monkey patched so that the <code>ca</code> field is not supported.
Instead we replace it with two fields <code>caAppend</code> and <code>caReplace</code>.</p>
</blockquote>
<p>Below we'll run a TLS server using a custom CA certificate. We'll
compare the difference in behavior between <code>curl</code> and Node.js when making
TLS requests to this server and to <code>google.com</code> with the same configuration.
Finally, after seeing how Node.js differs from <code>curl</code> in this regard, we'll
show how to use the <code>ca-append</code> <a href="https://www.npmjs.com/package/ca-append">package</a> to fix the issues with the
<code>ca</code> TLS option in Node.js.</p>
<p>See <a href="/2021/05/node-ca-footgun.html">The Node.js CA Footgun</a> for more details on a real world situation
that showcases a problematic situation caused by the behavior of the <code>ca</code>
TLS option.</p>
<ul>
<li><a href="#server">Server</a></li>
<li><a href="#clients">Clients</a></li>
<li><a href="#append-vs-replace">Append vs. Replace</a></li>
<li><a href="#patching-node-js">Patching Node.js</a></li>
</ul>
<h3 id="server">Server</h3>
<p>We can <a href="/code/node-ca/server.ts">define</a> a hello world TLS / HTTPS server with a
<a href="/code/node-ca/localhost-key.pem">private key</a> / X.509 <a href="/code/node-ca/localhost-cert.pem">certificate</a> pair for <code>localhost</code>:</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">key</span>: <span class="kt">fs.readFileSync</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">__dirname</span><span class="si">}</span><span class="sb">/localhost-key.pem`</span><span class="p">),</span>
<span class="nx">cert</span>: <span class="kt">fs.readFileSync</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="nx">__dirname</span><span class="si">}</span><span class="sb">/localhost-cert.pem`</span><span class="p">),</span>
<span class="p">};</span>
<span class="nx">https</span>
<span class="p">.</span><span class="nx">createServer</span><span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="p">(</span><span class="nx">_req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">res</span><span class="p">.</span><span class="nx">writeHead</span><span class="p">(</span><span class="mf">200</span><span class="p">);</span>
<span class="nx">res</span><span class="p">.</span><span class="nx">end</span><span class="p">(</span><span class="s1">'hello world\n'</span><span class="p">);</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">port</span><span class="p">);</span>
</code></pre></div>
<p>Running this server on port 9072, we'll attempt to securely connect
to it in a number of different ways:</p>
<div class="highlight"><pre><span></span><code>$ npx ts-node server.ts 9072
Running TLS server on localhost:9072
</code></pre></div>
<h3 id="clients">Clients</h3>
<h4><code>curl</code> Command Line Client</h4>
<p>By default, clients don't trust an X.509 certificate signed by a custom CA:</p>
<div class="highlight"><pre><span></span><code>$ curl https://localhost:9072
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
</code></pre></div>
<p>so we need to supply a custom CA <a href="/code/node-ca/root-ca-cert.pem">certificate</a>:</p>
<div class="highlight"><pre><span></span><code>$ curl --cacert ./root-ca-cert.pem https://localhost:9072
hello world
</code></pre></div>
<h4 id="node-with-ca">Node.js Client</h4>
<p>Similarly when using Node.js, the default client options can't verify the
server. However, when specifying <code>ca</code> to point at the custom root CA, the
connection succeeds. Running a <code>client.ts</code> <a href="/code/node-ca/client.ts">script</a> we see:</p>
<div class="highlight"><pre><span></span><code>$ npx ts-node client.ts https://localhost:9072
Using URL="https://localhost:9072";
Failure when `ca` not included:
error code: UNABLE_TO_VERIFY_LEAF_SIGNATURE
error message: unable to verify the first certificate
Success when `ca` included:
response.status: 200
</code></pre></div>
<p>These two requests are made with slightly different configurations:</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span> <span class="nx">withoutCA</span>: <span class="kt">axios.AxiosRequestConfig</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">httpsAgent</span>: <span class="kt">new</span> <span class="nx">https</span><span class="p">.</span><span class="nx">Agent</span><span class="p">({</span>
<span class="c1">// ...</span>
<span class="p">}),</span>
<span class="c1">// ...</span>
<span class="p">};</span>
<span class="kd">const</span> <span class="nx">withCA</span>: <span class="kt">axios.AxiosRequestConfig</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">httpsAgent</span>: <span class="kt">new</span> <span class="nx">https</span><span class="p">.</span><span class="nx">Agent</span><span class="p">({</span>
<span class="nx">ca</span><span class="o">:</span> <span class="p">[</span><span class="nx">customRootCA</span><span class="p">],</span>
<span class="c1">// ...</span>
<span class="p">}),</span>
<span class="c1">// ...</span>
<span class="p">};</span>
</code></pre></div>
<h3 id="append-vs-replace">Append vs. Replace</h3>
<h4><code>curl</code> Command Line Client</h4>
<p>When reaching public servers like <code>google.com</code>, <code>curl</code> can utilize the
root trust store by default:</p>
<div class="highlight"><pre><span></span><code>$ curl \
> --write-out "Status Code: %{http_code}\n" --output /dev/null --silent \
> https://www.google.com/
Status Code: 200
</code></pre></div>
<p>and supplying <code>--cacert</code> doesn't impede this connection:</p>
<div class="highlight"><pre><span></span><code>$ curl \
> --write-out "Status Code: %{http_code}\n" --output /dev/null --silent \
> --cacert ./root-ca-cert.pem \
> https://www.google.com/
Status Code: 200
</code></pre></div>
<p>In other words, <code>--cacert</code> <strong>appends</strong> to the root trust store (as opposed to
<strong>replacing</strong> it).</p>
<h4>Node.js Client</h4>
<p>On the other hand, using our Node.js client to reach Google's servers, we
see that the presence of <code>ca</code> keeps us from trusting a CA in our root trust
store:</p>
<div class="highlight"><pre><span></span><code>$ npx ts-node client.ts https://www.google.com/
Using URL="https://www.google.com/";
Success when `ca` not included:
response.status: 200
Failure when `ca` included:
error code: UNABLE_TO_GET_ISSUER_CERT_LOCALLY
error message: unable to get local issuer certificate
</code></pre></div>
<p>This should be somewhat jarring; we expect the CA for <code>google.com</code> to
<strong>always</strong> be trustworthy.</p>
<h3 id="patching-node-js">Patching Node.js</h3>
<p>In order to fix this problem with Node.js, i.e. to provide a way to
<strong>append to</strong> rather than <strong>replace</strong> the root trust store, I have
<a href="https://github.com/dhermes/ca-append-js">written</a> the <code>ca-append</code> package. To use the package, import it and
activate the monkey patch:</p>
<div class="highlight"><pre><span></span><code><span class="k">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">caAppend</span> <span class="k">from</span> <span class="s1">'ca-append'</span><span class="p">;</span>
<span class="nx">caAppend</span><span class="p">.</span><span class="nx">monkeyPatch</span><span class="p">();</span>
</code></pre></div>
<p>and it will monkey patch the core <code>tls.createSecureContext()</code> function.</p>
<p>Once patched, the <code>ca</code> option will be rejected and replaced with choices that
are more descriptive: <code>caAppend</code> and <code>caReplace</code>. Let's see the <code>caAppend</code>
option in use as well as <strong>rejection</strong> of the <code>ca</code> option. First we'll
re-attempt communicating with our server running on <code>localhost</code> and
observe the same behavior we saw above in <a href="#node-with-ca">Node.js Client</a>:</p>
<div class="highlight"><pre><span></span><code>$ npx ts-node clientPatched.ts https://localhost:9072
Using URL="https://localhost:9072";
Failure when `ca` / `caAppend` not included:
error code: UNABLE_TO_VERIFY_LEAF_SIGNATURE
error message: unable to verify the first certificate
Failure when `ca` included:
error code: undefined
error message: tls.createSecureContext(): `ca` option has been deprecated
Success when `caAppend` included:
response.status: 200
</code></pre></div>
<p>The connection to Google servers now works in both cases as well:</p>
<div class="highlight"><pre><span></span><code>$ npx ts-node clientPatched.ts https://www.google.com/
Using URL="https://www.google.com/";
Success when `ca` / `caAppend` not included:
response.status: 200
Failure when `ca` included:
error code: undefined
error message: tls.createSecureContext(): `ca` option has been deprecated
Success when `caAppend` included:
response.status: 200
</code></pre></div>
<p>This all comes from <a href="/code/node-ca/clientPatched.ts">using</a> <code>caAppend</code> in <code>clientPatched.ts</code>:</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span> <span class="nx">optionsWithCAAppend</span> <span class="o">=</span> <span class="nx">makeOptions</span><span class="p">({</span> <span class="nx">caAppend</span><span class="o">:</span> <span class="p">[</span><span class="nx">customRootCA</span><span class="p">]</span> <span class="p">});</span>
</code></pre></div>
<p>versus using <code>ca</code> in <code>client.ts</code>:</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span> <span class="nx">optionsWith</span> <span class="o">=</span> <span class="nx">makeOptions</span><span class="p">({</span> <span class="nx">ca</span><span class="o">:</span> <span class="p">[</span><span class="nx">customRootCA</span><span class="p">]</span> <span class="p">});</span>
</code></pre></div>
<h3 id="post-script">Post Script: Warning</h3>
<p>The Node.js module system returns a singleton for every import, so once
<code>ca-append</code> monkey patches the <code>tls</code> package, every other import of
<code>tls</code> will see the effects. This will likely not be directly visible in
application code; <code>tls</code> is more likely to be imported transitively in an
application by packages that provide HTTP / HTTPS clients.</p>The Node.js CA Footgun2021-05-11T00:00:00-07:002021-05-11T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-05-11:/2021/05/node-ca-footgun.html<div style="text-align: center;">
<p><img alt="Door to Nowhere" src="/images/door-nowhere.jpg"></p>
</div>
<p>This is a story of a brief outage caused by a slightly unintuitive API<sup id=sf-node-ca-footgun-1-back><a href=#sf-node-ca-footgun-1 class=simple-footnote title="Like a door to nowhere.">1</a></sup> that has some very <a href="https://en.wiktionary.org/wiki/footgun">sharp corners</a> for the
uninitiated. The outage, though brief, was of the "wake up at 4am" variety so
the lesson was especially salient.</p>
<p>This <strong>is not</strong> a post trying to tear …</p><div style="text-align: center;">
<p><img alt="Door to Nowhere" src="/images/door-nowhere.jpg"></p>
</div>
<p>This is a story of a brief outage caused by a slightly unintuitive API<sup id=sf-node-ca-footgun-1-back><a href=#sf-node-ca-footgun-1 class=simple-footnote title="Like a door to nowhere.">1</a></sup> that has some very <a href="https://en.wiktionary.org/wiki/footgun">sharp corners</a> for the
uninitiated. The outage, though brief, was of the "wake up at 4am" variety so
the lesson was especially salient.</p>
<p>This <strong>is not</strong> a post trying to tear down the Node.js authors or cast blame.
The Node.js runtime and standard library are incredible force multipliers
that help teams ship code quickly. This particular story is about a codebase
misusing the connection options offered by the <code>tls</code> package in the Node.js
standard library. This usage was based on an "obvious" interpretation of one
option name and an expectation that another option would behave similarly to
how it works in other technology stacks. These options are very
well documented, but one option could really benefit from being renamed and the
other could benefit from a small change in behavior. However, for a programming
language runtime with such a large userbase it's essentially impossible to
rename options or change behavior in a core package once released.</p>
<h3>Contents</h3>
<ul>
<li><a href=#the-good>The Good</a></li>
<li><a href=#the-bad>The Bad</a></li>
<li><a href=#the-ugly>The Ugly</a></li>
<li><a href=#takeaways>Takeaways</a></li>
</ul>
<h3 id=the-good>The Good</h3>
<p>This outage motivated me to try to address the biggest issue in this
outage: the <code>ca</code> TLS option wipes away the default root trust store.
I wrote <a href="/2021/05/node-ca-append.html">Fixing the Custom CA Problem in Node.js</a> to showcase
how <code>ca</code> is currently broken and to demonstrate how my <code>ca-append</code> <a href="https://github.com/dhermes/ca-append-js">package</a>
tries to patch the brokenness.</p>
<h3 id=the-bad>The Bad</h3>
<p>Here I want to lay out the sharpest corner: the <code>ca</code> TLS option in Node.js
(I mentioned two connection options in this story, but the second one —
<code>cert</code> — was a less significant contributor to the outage).</p>
<p>When applications securely connect over TLS, they always<sup id=sf-node-ca-footgun-2-back><a href=#sf-node-ca-footgun-2 class=simple-footnote title="Almost always. But they should always verify.">2</a></sup> verify that the server's X.509 certificate
has been signed by a trusted certificate authority (CA). Most language
runtimes — including Node.js — have a default root trust store of
well-known CAs.</p>
<p>However, some applications need to connect to private or internal servers that
have X.509 certificates signed by a CA <strong>outside of</strong> the default root trust
store. For example, during local development we may want to run a server over
TLS on <code>localhost</code>. Or, some third parties may have a private CA that
they use to sign certificates for internal APIs.</p>
<p>In these situations it's crucial to be able to modify the default root trust
store and Node.js provides a <code>ca</code> TLS connection option<sup id=sf-node-ca-footgun-3-back><a href=#sf-node-ca-footgun-3 class=simple-footnote title=' Node.js also supports a NODE_EXTRA_CA_CERTS environment variable for the custom CA use case. However, NODE_EXTRA_CA_CERTS is a "catch-all" that applies to every connection, which can be a problem in multi-tenant applications.'>3</a></sup> for doing just that. The problem with the <a href="https://nodejs.org/docs/latest-v14.x/api/tls.html#tls_tls_createsecurecontext_options"><code>ca</code> option</a>
is that it completely replaces the existing trust store (rather than appending
to it):</p>
<blockquote>
<p>Optionally override the trusted CA certificates. Default is to trust the
well-known CAs curated by Mozilla. Mozilla's CAs are completely replaced
when CAs are explicitly specified using this option.</p>
</blockquote>
<p>This means that we can no longer hit public servers over TLS if the <code>ca</code> option
is used. For example, we'd expect to be able to communicate with
<code>https://www.google.com</code> but unless the CA that signed the Google public
certificate is present in our <code>ca</code> input, the connection will fail.</p>
<h3 id=the-ugly>The Ugly</h3>
<p>We'll start with the outage here and then work our way backwards to understand
how the code and configuration got in a brittle and then broken state.
To tell the story of the outage, I'll introduce a fictional API and private
CA, but keep the core ideas intact. The API uses mutual TLS (mTLS)
to authenticate requests, so the the characters in the story are as follows:</p>
<ul>
<li><strong>Server</strong>: <code>https://api.acme.invalid</code></li>
<li><strong>Server Root CA</strong>: DigiCert<sup id=sf-node-ca-footgun-4-back><a href=#sf-node-ca-footgun-4 class=simple-footnote title="DigiCert is one of the most reputable Certificate Authorities, if not the most reputable.">4</a></sup></li>
<li><strong>Client Root CA</strong>: Acme Corp Legitimate Root CA</li>
</ul>
<p>Both the server and client public certificate were signed by
intermediates<sup id=sf-node-ca-footgun-5-back><a href=#sf-node-ca-footgun-5 class=simple-footnote title="As opposed to being directly signed by the root CA.">5</a></sup>
as well:</p>
<div class=highlight><pre><span></span><code>Root CN: DigiCert High Assurance EV Root CA
Intermediate CN: DigiCert SHA2 Extended Validation Server CA
Leaf CN: api.acme.invalid
Root CN: Acme Corp Legitimate Root CA
Intermediate CN: Acme Corp Production Intermediate CA
Leaf CN: 3975092b-4484-4b36-9f22-f84d4dd1e95a
</code></pre></div>
<p>In order to sign mTLS requests as the client, the TLS connection was configured
with a public certificate, a private key and a pair of
relevant CAs<sup id=sf-node-ca-footgun-6-back><a href=#sf-node-ca-footgun-6 class=simple-footnote title="The astute observer may notice one CA is an intermediate and the other is a root. This is not a typo, but is also not something that is particularly correct. More on that later.">6</a></sup>:</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>options</span>: <span class=kt>tls.SecureContextOptions</span> <span class=o>=</span> <span class=p>{</span>
<span class=nx>key</span>: <span class=kt>fs.readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/client-key.pem`</span><span class=p>),</span>
<span class=nx>cert</span>: <span class=kt>fs.readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/client-cert.pem`</span><span class=p>),</span>
<span class=nx>ca</span><span class=o>:</span> <span class=p>[</span>
<span class=nx>fs</span><span class=p>.</span><span class=nx>readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/client-intermediate.pem`</span><span class=p>),</span>
<span class=nx>fs</span><span class=p>.</span><span class=nx>readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/DigiCertHighAssuranceEVRootCA.crt.pem`</span><span class=p>),</span>
<span class=p>],</span>
<span class=p>}</span>
</code></pre></div>
<p>Unfortunately, the <code>api.acme.invalid</code> certificate <strong>expired</strong> 23 months after
the code using this configuration was written and deployed. This is a textbook
case of "it works today, ship it" gone wrong. The service and API integration
worked perfectly fine for 22 months. Then, when Acme rotated the server
certificate, everything fell apart.</p>
<p>From Acme's perspective, nothing had changed about the <code>api.acme.invalid</code>
server because the new certificate was from DigiCert as well. As a result,
no communications or warnings were sent out to the API clients when the
certificate was rotated. However, DigiCert has <strong>multiple</strong> roots and the
new certificate was issued by a <strong>different</strong> CA certificate:</p>
<div class=highlight><pre><span></span><code>Root CN: DigiCert Global Root CA
Intermediate CN: DigiCert TLS RSA SHA256 2020 CA1
Leaf CN: api.acme.invalid
</code></pre></div>
<p>Now the addition of <code>DigiCertHighAssuranceEVRootCA.crt.pem</code> to the <code>ca</code>
override provides no help. After the server certificate was rotated, a
<code>SELF_SIGNED_CERT_IN_CHAIN</code> error immediately started to occur on
<strong>every request</strong> to the Acme API<sup id=sf-node-ca-footgun-7-back><a href=#sf-node-ca-footgun-7 class=simple-footnote title="This error indicates that the CA — DigiCert Global Root CA — is not trusted by the custom ca bundle override used by the application.">7</a></sup>. Worse still, the on-call
engineer at the time had insufficient context on the original implementation
and had <strong>never seen</strong> this self-signed certificate error before. Combined
with the fact that Acme had not sent out change notifications, the code had
not changed and the service had not been redeployed recently, this sudden
outage was confounding.</p>
<p>Once the on-call engineer pulled in another team more familiar with
TLS, the error was clear but the source of the configuration was not.
Eventually, the <code>ca</code> override was found collaboratively and the API
integration was fixed by adding <code>DigiCertGlobalRootCA.crt.pem</code> to the <code>ca</code>
bundle override.</p>
<h4 id=why-override>Why Override <code>ca</code> at All?</h4>
<p>In sensitive or zero trust environments, it's common to use mutual TLS (mTLS).
Often in this scenario, an API provider will run a private CA and will use
it to sign <a href="https://en.wikipedia.org/wiki/Certificate_signing_request">CSRs</a> for client certificates. When working with Acme Corp to
get a valid client certificate, the team generated a private key file
<code>client-key.pem</code> and sent off a CSR. Acme Corp gladly signed the CSR and sent
back the file <code>client-chain.pem</code>. This chain file contained both the public
certificate <code>3975092b-4484-4b36-9f22-f84d4dd1e95a</code> and the
Acme Corp Production Intermediate CA certificate.</p>
<p>The <strong>name</strong> of the <code>cert</code> option is what caused confusion and triggered the
brittle outage-inducing configuration. After a literal reading of the names
<code>cert</code> and <code>ca</code> in the TLS options, the team decided to split the up
<code>client-chain.pem</code> into two files:</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>options</span>: <span class=kt>tls.SecureContextOptions</span> <span class=o>=</span> <span class=p>{</span>
<span class=nx>key</span>: <span class=kt>fs.readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/client-key.pem`</span><span class=p>),</span>
<span class=nx>cert</span>: <span class=kt>fs.readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/client-cert.pem`</span><span class=p>),</span>
<span class=nx>ca</span><span class=o>:</span> <span class=p>[</span><span class=nx>fs</span><span class=p>.</span><span class=nx>readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/client-intermediate.pem`</span><span class=p>)],</span>
<span class=p>}</span>
</code></pre></div>
<p>However, attempting to using this configuration during development failed
(as expected): <code>SELF_SIGNED_CERT_IN_CHAIN</code><sup id=sf-node-ca-footgun-8-back><a href=#sf-node-ca-footgun-8 class=simple-footnote title="The self-signed error occurs if a server presents a full chain, i.e. leaf, intermediate and root. However, it's more common for a server to only present a leaf and intermediate, in which case the equivalent Node.js error would be UNABLE_TO_GET_ISSUER_CERT_LOCALLY.">8</a></sup>.
This error is caused by the <code>ca</code> issue discussed <a href=#the-bad>above</a>: the root
DigiCert High Assurance EV Root CA was no longer trusted in the connection
because all of the default public root CAs have been replaced. In order to
solve this connection issue, the team <a href="https://www.digicert.com/kb/digicert-root-certificates.htm">downloaded</a>
<code>DigiCertHighAssuranceEVRootCA.crt.pem</code> and added it to the <code>ca</code> override.</p>
<h4 id=could-avoided>Could This Have Been Avoided?</h4>
<p>If the team had used <code>client-chain.pem</code> directly, there would have been no need
to override the <code>ca</code> in the connection:</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>options</span>: <span class=kt>tls.SecureContextOptions</span> <span class=o>=</span> <span class=p>{</span>
<span class=nx>key</span>: <span class=kt>fs.readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/client-key.pem`</span><span class=p>),</span>
<span class=nx>cert</span>: <span class=kt>fs.readFileSync</span><span class=p>(</span><span class=sb>`</span><span class=si>${</span><span class=nx>CONFIGURATION_DIR</span><span class=si>}</span><span class=sb>/client-chain.pem`</span><span class=p>),</span>
<span class=p>}</span>
</code></pre></div>
<p>If <strong>only</strong> the leaf certificate<sup id=sf-node-ca-footgun-9-back><a href=#sf-node-ca-footgun-9 class=simple-footnote title="The alternative to only the leaf certificate is a chain file containing both the leaf certificate and the intermediate CA that signed it.">9</a></sup> is
used in the <code>cert</code> option, many servers will fail an mTLS request with
<code>UNABLE_TO_VERIFY_LEAF_SIGNATURE</code> or a similar error. This is because the
client party must present the leaf certificate <strong>and</strong> any intermediates
along the chain up to the root CA. The documentation for <code>cert</code>
<a href="https://nodejs.org/docs/latest-v14.x/api/tls.html#tls_tls_createsecurecontext_options">makes this clear</a></p>
<blockquote>
<p>Cert chains in PEM format ... Each cert chain should consist of the PEM
formatted certificate for a provided private key, followed by the PEM
formatted intermediate certificates (if any), in order, and not including
the root CA (the root CA must be pre-known to the peer, see <code>ca</code>).</p>
</blockquote>
<p>Renaming the option from <code>cert</code> to <code>chain</code> in the <code>tls</code> package would be much
clearer. But the Node.js runtime and the standard library <code>tls</code> package have
<strong>wide</strong> usage and such a rename is likely impossible to pull off.</p>
<p>Once the intermediate CA is removed from the file used in <code>cert</code>, Node.js
can't hope to present the intermediate CA certificate during an mTLS handshake.
However, if the intermediate CA certificate is added via <code>ca</code>, Node.js can
find it in the root trust store and then present it to the server as the issuer
of the leaf.</p>
<h4 id=rotation-blame>Is the Server Certificate Rotation to Blame?</h4>
<blockquote>
<p><strong>TL;DR</strong>: No</p>
</blockquote>
<p>By design, X.509 certificates issued by public CAs expire often because they
have short lifetimes (typically <a href="https://letsencrypt.org/2015/11/09/why-90-days.html">ninety days</a> to two years). Shorter
lifetimes require certificate and key rotations. Rotations help limit the
impact of key compromise and help make sure the public internet "upgrades" key
strength as technology improves.</p>
<h3 id=takeaways>Takeaways</h3>
<blockquote>
<p>This is a textbook case of "it works today, ship it" gone wrong.</p>
</blockquote>
<p>The connection option misuse described here was exacerbated by service
operators lacking familiarity with the class of errors typical when TLS
connections fail. But TLS is squarely one of those "here be dragons" topics for
most engineering teams (including information security teams). The takeaways
from this outage are not cut and dry:</p>
<ul>
<li>It's unreasonable for every type of engineering team to have deep knowledge
in this part of the stack, on-call service operators should <strong>quickly</strong>
loop in teams or people that do have that knowledge during an outage</li>
<li>Teams that don't have deep knowledge of a given technology (e.g. TLS),
should try to avoid "deep" customization when using it or try to share
the burden of the complexity e.g. by using an auxiliary service provided
by another team</li>
<li>Writing "tests" for things that work today but might break in the future
is <strong>very hard</strong>. "Modern" software tooling is very good, but there
are many kinds of assumptions that are just not possible to encode in
unit tests or acceptance tests in today's landscape</li>
</ul>
<hr style="margin-bottom: 25px; width: 50%;"><ol class=simple-footnotes><li id=sf-node-ca-footgun-1>Like
a door to nowhere. <a href=#sf-node-ca-footgun-1-back class=simple-footnote-back>↩</a></li><li id=sf-node-ca-footgun-2>Almost always. But
they <strong>should</strong> always verify. <a href=#sf-node-ca-footgun-2-back class=simple-footnote-back>↩</a></li><li id=sf-node-ca-footgun-3>
Node.js also supports a <code>NODE_EXTRA_CA_CERTS</code> environment variable for the
custom CA use case. However, <code>NODE_EXTRA_CA_CERTS</code> is a "catch-all" that
applies to every connection, which can be a problem in multi-tenant
applications. <a href=#sf-node-ca-footgun-3-back class=simple-footnote-back>↩</a></li><li id=sf-node-ca-footgun-4>DigiCert is one of the most
reputable Certificate Authorities, if not <strong>the</strong> most reputable. <a href=#sf-node-ca-footgun-4-back class=simple-footnote-back>↩</a></li><li id=sf-node-ca-footgun-5>As opposed to being directly signed by the root CA. <a href=#sf-node-ca-footgun-5-back class=simple-footnote-back>↩</a></li><li id=sf-node-ca-footgun-6>The astute observer may notice one CA is an intermediate
and the other is a root. This is not a typo, but is also not something
that is particularly correct. More on that later. <a href=#sf-node-ca-footgun-6-back class=simple-footnote-back>↩</a></li><li id=sf-node-ca-footgun-7>This error indicates that the
CA — DigiCert Global Root CA — is not trusted by the custom <code>ca</code>
bundle override used by the application. <a href=#sf-node-ca-footgun-7-back class=simple-footnote-back>↩</a></li><li id=sf-node-ca-footgun-8>The self-signed error occurs if
a server presents a <strong>full</strong> chain, i.e. leaf, intermediate and root. However,
it's more common for a server to only present a leaf and intermediate, in
which case the equivalent Node.js error would be
<code>UNABLE_TO_GET_ISSUER_CERT_LOCALLY</code>. <a href=#sf-node-ca-footgun-8-back class=simple-footnote-back>↩</a></li><li id=sf-node-ca-footgun-9>The alternative to <strong>only</strong> the
leaf certificate is a chain file containing both the leaf certificate
and the intermediate CA that signed it. <a href=#sf-node-ca-footgun-9-back class=simple-footnote-back>↩</a></li></ol>Custom GitHub Actions2021-03-03T00:00:00-08:002021-03-03T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-03-03:/2021/03/custom-github-actions.html<p>The "obvious" way to write a custom GitHub Action is using Node.js, however
it's not the only way. As it turns out, a GitHub Action really just
communicates with the "orchestrator" via environment variables (as inputs)
and STDOUT (to produce custom outputs).</p>
<h3>Options</h3>
<p>When defining an action, there are …</p><p>The "obvious" way to write a custom GitHub Action is using Node.js, however
it's not the only way. As it turns out, a GitHub Action really just
communicates with the "orchestrator" via environment variables (as inputs)
and STDOUT (to produce custom outputs).</p>
<h3>Options</h3>
<p>When defining an action, there are (as of this writing) three ways to
determine how it gets invoked</p>
<div class=highlight><pre><span></span><code><span class=nt>runs</span><span class=p>:</span>
<span class=nt>using</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">node12</span>
<span class=nt>main</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">index.js</span>
<span class=c1># OR</span>
<span class=nt>runs</span><span class=p>:</span>
<span class=nt>using</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">docker</span>
<span class=nt>main</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">Dockerfile</span>
<span class=c1># OR</span>
<span class=nt>runs</span><span class=p>:</span>
<span class=nt>using</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">composite</span>
<span class=nt>steps</span><span class=p>:</span>
<span class="p p-Indicator">-</span> <span class=nt>run</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">${{ github.action_path }}/main.sh</span>
<span class=nt>shell</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">bash</span>
</code></pre></div>
<p>I was hoping to lean on some mature Go tooling to write an action in Go, so
that ruled out <code>using: node12</code>. Additionally, by having a custom <code>Dockerfile</code>,
we would force all users of an action to wait through <code>docker build</code> on
every invocation of the action. This left <code>using: composite</code> as the early
leader.</p>
<p>When running with <code>using: composite</code>, I found that my <code>main.sh</code> executed just
fine, but there were two problems that made it <strong>not</strong> an
option<sup id=sf-custom-github-actions-1-back><a href=#sf-custom-github-actions-1 class=simple-footnote title="Both of these issues may just be a symptom of the version of GitHub Enterprise we are running, so we can likely revisit">1</a></sup>:</p>
<ul>
<li>None of the <code>INPUT_*</code> environment variables were passed in to my script</li>
<li>My <code>STDOUT</code> was not being interpreted and used</li>
<li>The <code>ACTIONS_RUNTIME_TOKEN</code> and <code>ACTIONS_RUNTIME_URL</code> environment variables
were absent</li>
</ul>
<h3>A Path Forward</h3>
<p>In order to invoke my shell script <strong>as if</strong> it were <code>using: node12</code>, I
introduced the following shim</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>childProcess</span> <span class=o>=</span> <span class=nx>require</span><span class=p>(</span><span class=s2>"child_process"</span><span class=p>);</span>
<span class=kd>const</span> <span class=nx>process</span> <span class=o>=</span> <span class=nx>require</span><span class=p>(</span><span class=s2>"process"</span><span class=p>);</span>
<span class=kd>function</span> <span class=nx>main</span><span class=p>()</span> <span class=p>{</span>
<span class=kd>const</span> <span class=nx>mainScript</span> <span class=o>=</span> <span class=sb>`</span><span class=si>${</span><span class=nx>__dirname</span><span class=si>}</span><span class=sb>/main.sh`</span><span class=p>;</span>
<span class=kd>const</span> <span class=nx>spawnSyncReturns</span> <span class=o>=</span> <span class=nx>childProcess</span><span class=p>.</span><span class=nx>spawnSync</span><span class=p>(</span><span class=nx>mainScript</span><span class=p>,</span> <span class=p>{</span>
<span class=nx>stdio</span><span class=o>:</span> <span class=s2>"inherit"</span><span class=p>,</span>
<span class=p>});</span>
<span class=kd>const</span> <span class=nx>status</span> <span class=o>=</span> <span class=nx>spawnSyncReturns</span><span class=p>.</span><span class=nx>status</span><span class=p>;</span>
<span class=k>if</span> <span class=p>(</span><span class=k>typeof</span> <span class=nx>status</span> <span class=o>===</span> <span class=s2>"number"</span><span class=p>)</span> <span class=p>{</span>
<span class=nx>process</span><span class=p>.</span><span class=nx>exit</span><span class=p>(</span><span class=nx>status</span><span class=p>);</span>
<span class=p>}</span>
<span class=nx>process</span><span class=p>.</span><span class=nx>exit</span><span class=p>(</span><span class=mf>1</span><span class=p>);</span>
<span class=p>}</span>
<span class=k>if</span> <span class=p>(</span><span class=nx>require</span><span class=p>.</span><span class=nx>main</span> <span class=o>===</span> <span class=nx>module</span><span class=p>)</span> <span class=p>{</span>
<span class=nx>main</span><span class=p>();</span>
<span class=p>}</span>
</code></pre></div>
<p>and just specified</p>
<div class=highlight><pre><span></span><code><span class=nt>runs</span><span class=p>:</span>
<span class=nt>using</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">node12</span>
<span class=nt>main</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">index.js</span>
</code></pre></div>
<p>Here <code>main.sh</code> can be replaced with <strong>any</strong> binary, so long as it can run on the
current system<sup id=sf-custom-github-actions-2-back><a href=#sf-custom-github-actions-2 class=simple-footnote title="This requires knowing the architecture and possibly which packages are already installed on the machine. I.e. easier said than done.">2</a></sup>. For example, a Go static binary targeting Linux would likely work.</p>
<h3>GitHub Actions Inputs and Outputs</h3>
<p>One of the official ways to implement a GitHub action is the <code>@actions/core</code>
package on the <code>npm</code> <a href="https://www.npmjs.com/package/@actions/core">public registry</a>. However, each method provided
there really wraps primitives that interact with environment variables or
<code>STDOUT</code> and it is these primitives that would enable writing an action in
Go, Python or any other language of our choosing.</p>
<p>For each function provided by <code>@actions/core</code><sup id=sf-custom-github-actions-3-back><a href=#sf-custom-github-actions-3 class=simple-footnote title="This is as of version 1.2.6.">3</a></sup>, see below the equivalent low-level / non-JavaScript equivalent.</p>
<h4><code>core.exportVariable(name: string, val: any): void</code></h4>
<p>This appends to the file at the location specified by the <code>${GITHUB_ENV}</code>
environment variable. For example if we want to set the environment variable
<code>NEWLY=ADDED</code> the following three lines would be appended:</p>
<div class=highlight><pre><span></span><code>NEWLY<<_GitHubActionsFileCommandDelimeter_
ADDED
_GitHubActionsFileCommandDelimeter_
</code></pre></div>
<blockquote>
<p><strong>Note</strong>: In cases where a name has a "protected" character like <code>:</code> in it,
the character will be replaced by <code>%3A</code> or the URL / percent encoded
equivalent. (This means also that <code>%</code> must be encoded as <code>%25</code>.)</p>
</blockquote>
<h4><code>core.setSecret(secret: string): void</code></h4>
<p>This writes a line to STDOUT of the form:</p>
<div class=highlight><pre><span></span><code>::add-mask::${secret}
</code></pre></div>
<h4><code>core.addPath(inputPath: string): void</code></h4>
<p>This appends to the file at the location specified by the <code>${GITHUB_PATH}</code>
environment variable. This just appends a line with the path to be added.</p>
<h4><code>core.getInput(name: string, options?: InputOptions): string</code></h4>
<p>This reads from the <code>${INPUT_[allcaps(name)]}</code> environment variable and then
<strong>trims</strong> any whitespace via <code>String.prototype.trim</code>. For example if <code>name</code> is
<code>'k'</code> then we look in <code>${INPUT_K}</code>. The literal transformation to <code>name</code> is</p>
<div class=highlight><pre><span></span><code><span class=sb>`INPUT_</span><span class=si>${</span><span class=nx>name</span><span class=p>.</span><span class=nx>replace</span><span class=p>(</span><span class=sr>/ /g</span><span class=p>,</span> <span class=s2>"_"</span><span class=p>).</span><span class=nx>toUpperCase</span><span class=p>()</span><span class=si>}</span><span class=sb>`</span><span class=p>;</span>
</code></pre></div>
<h4><code>core.setOutput(name: string, value: any): void</code></h4>
<p>Print to <code>STDOUT</code>, e.g. <code>::set-output name=${name}::${value}"</code></p>
<h4><code>core.setCommandEcho(enabled: boolean): void</code></h4>
<p>This prints either <code>::echo::on</code> or <code>::echo::off</code> to <code>STDOUT</code></p>
<h4><code>core.setFailed(message: string | Error): void</code></h4>
<p>The message is printed to <code>STDOUT</code>, e.g. if the error message is
"Cannot find widget" then we would print</p>
<div class=highlight><pre><span></span><code>::error::Cannot find widget
</code></pre></div>
<p>to STDOUT and the process exits with 1</p>
<h4><code>core.isDebug(): boolean</code></h4>
<p>Checks if the <code>${RUNNER_DEBUG}</code> environment variable is set to <code>1</code></p>
<h4><code>core.debug(message: string): void</code></h4>
<p>Prints <code>::debug::${message}</code> to <code>STDOUT</code></p>
<h4><code>core.error(message: string | Error): void</code></h4>
<p>Prints <code>::error::${message}</code> to <code>STDOUT</code></p>
<h4><code>core.warning(message: string | Error): void</code></h4>
<p>Prints <code>::warning::${message}</code> to <code>STDOUT</code></p>
<h4><code>core.info(message: string): void</code></h4>
<p>Prints <code>${message}</code> to <code>STDOUT</code></p>
<h4><code>core.startGroup(name: string): void</code></h4>
<p>Prints <code>::group::${name}</code> to <code>STDOUT</code></p>
<h4><code>core.endGroup(): void</code></h4>
<p>Prints <code>::endgroup::</code> to <code>STDOUT</code></p>
<h4><code>core.group<T>(name: string, fn: () => Promise<T>): Promise<T></code></h4>
<p>Starts and ends a group and then allows <code>fn</code> to modify <code>STDOUT</code> in between.
For example if <code>fn</code> were to print out <code>::warning::Slow build</code> then that
given invocation of <code>core.group('FYI', fn)</code> would produce</p>
<div class=highlight><pre><span></span><code>::group::FYI
::warning::Slow build
::endgroup::
</code></pre></div>
<h4><code>core.saveState(name: string, value: any): void</code></h4>
<p>Prints a line to STDOUT containing the name and a JSON-serialized (without
newlines) version of <code>value</code>. For example, invoking via</p>
<div class=highlight><pre><span></span><code><span class=nx>core</span><span class=p>.</span><span class=nx>saveState</span><span class=p>(</span><span class=s2>"config-map"</span><span class=p>,</span> <span class=p>{</span> <span class=nx>a</span><span class=o>:</span> <span class=s2>"b\nc"</span><span class=p>,</span> <span class=nx>d</span><span class=o>:</span> <span class=mf>2.718281828459045</span> <span class=p>});</span>
</code></pre></div>
<p>should produce</p>
<div class=highlight><pre><span></span><code>::save-state name=config-map::{"a":"b\nc","d":2.718281828459045}
</code></pre></div>
<h4><code>core.getState(name: string): string</code></h4>
<p>Reads from the <code>STATE_${name}</code> environment variable and returns the empty
string in the absence. Note that no JSON deserialization is attempted.</p>
<p>Also note that unlike for the <code>INPUT_</code> environment variable in
<code>core.getInput()</code>, there is no sanitization applied to <code>name</code>.</p>
<h3>Alternatives</h3>
<p>Another possible option (that has not yet been explored) would be to use</p>
<div class=highlight><pre><span></span><code><span class=nt>runs</span><span class=p>:</span>
<span class=nt>using</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">docker</span>
<span class=nt>image</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">docker://alpine:3.13.2</span>
<span class=nt>entrypoint</span><span class=p>:</span> <span class="l l-Scalar l-Scalar-Plain">main.sh</span>
</code></pre></div>
<p>Though it would require some testing to see</p>
<ul>
<li>which environment variables are present from within the container</li>
<li>which files / directories (if any) from the action are mounted in the
container</li>
<li>how the status code from the container propagates as part of the action</li>
<li>if STDOUT / STDERR in the container are treated the same way as
<code>using: node12</code> would be</li>
</ul><ol class=simple-footnotes><li id=sf-custom-github-actions-1>Both of these issues may just be a symptom of the version of GitHub
Enterprise we are running, so we can likely revisit <a href=#sf-custom-github-actions-1-back class=simple-footnote-back>↩</a></li><li id=sf-custom-github-actions-2>This requires knowing the architecture and possibly which
packages are already installed on the machine. I.e. easier said than
done. <a href=#sf-custom-github-actions-2-back class=simple-footnote-back>↩</a></li><li id=sf-custom-github-actions-3>This is as of <a href="https://www.npmjs.com/package/@actions/core/v/1.2.6">version</a>
<code>1.2.6</code>. <a href=#sf-custom-github-actions-3-back class=simple-footnote-back>↩</a></li></ol>HTTP Is Just Text2021-02-24T00:00:00-08:002021-02-24T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2021-02-24:/2021/02/http-is-just-text.html<p>This is a tiny little note that can help with debugging in some situations.
We'll use netcat (<code>nc</code>) to view the <strong>raw</strong> data sent to and returned from
an HTTP server<sup id=sf-http-is-just-text-1-back><a href=#sf-http-is-just-text-1 class=simple-footnote title="Note that HTTP/2 is a binary protocol so this only applies to HTTP/1.1.">1</a></sup>.</p>
<h3>Capture a Request</h3>
<p>We'll run a dummy listener via <code>nc</code> and directly inspect the body of an
HTTP …</p><p>This is a tiny little note that can help with debugging in some situations.
We'll use netcat (<code>nc</code>) to view the <strong>raw</strong> data sent to and returned from
an HTTP server<sup id=sf-http-is-just-text-1-back><a href=#sf-http-is-just-text-1 class=simple-footnote title="Note that HTTP/2 is a binary protocol so this only applies to HTTP/1.1.">1</a></sup>.</p>
<h3>Capture a Request</h3>
<p>We'll run a dummy listener via <code>nc</code> and directly inspect the body of an
HTTP request. To run the listener on port <code>6426</code> via <code>nc -l</code> (<code>-l</code> for listen)
and in another terminal, use <code>curl</code> to make a simple HTTP request</p>
<div class=highlight><pre><span></span><code>$ curl --max-time 1 http://localhost:6426
curl: (28) Operation timed out after 1005 milliseconds with 0 bytes received
</code></pre></div>
<p>In our other shell, we should see something like:</p>
<div class=highlight><pre><span></span><code>$ nc -l 6426
GET / HTTP/1.1
Host: localhost:6426
User-Agent: curl/7.64.1
Accept: */*
$
</code></pre></div>
<p>Let's write this to a file so we can keep it around later</p>
<div class=highlight><pre><span></span><code>$ nc -l 6426 > request.bin
$ hexdump -C request.bin
00000000 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a |GET / HTTP/1.1..|
00000010 48 6f 73 74 3a 20 6c 6f 63 61 6c 68 6f 73 74 3a |Host: localhost:|
00000020 36 34 32 36 0d 0a 55 73 65 72 2d 41 67 65 6e 74 |6426..User-Agent|
00000030 3a 20 63 75 72 6c 2f 37 2e 36 34 2e 31 0d 0a 41 |: curl/7.64.1..A|
00000040 63 63 65 70 74 3a 20 2a 2f 2a 0d 0a 0d 0a |ccept: */*....|
0000004e
</code></pre></div>
<p>In particular note that the newline characters are <code>0d 0a</code>, i.e. <code>\r\n</code>:</p>
<div class=highlight><pre><span></span><code>$ python
>>> b'\x0d\x0a'
b'\r\n'
</code></pre></div>
<h3>Capture a Response</h3>
<p>We'll use an Express server on port <code>6426</code> to capture an HTTP response:</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>express</span> <span class=o>=</span> <span class=nx>require</span><span class=p>(</span><span class=s2>"express"</span><span class=p>);</span>
<span class=kd>function</span> <span class=nx>main</span><span class=p>(</span><span class=nx>port</span><span class=p>)</span> <span class=p>{</span>
<span class=kd>const</span> <span class=nx>app</span> <span class=o>=</span> <span class=nx>express</span><span class=p>();</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>get</span><span class=p>(</span><span class=s2>"/"</span><span class=p>,</span> <span class=p>(</span><span class=nx>_req</span><span class=p>,</span> <span class=nx>res</span><span class=p>)</span> <span class=p>=></span> <span class=p>{</span>
<span class=nx>res</span><span class=p>.</span><span class=nx>send</span><span class=p>(</span><span class=s2>"Hello World!\n"</span><span class=p>);</span>
<span class=p>});</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>listen</span><span class=p>(</span><span class=nx>port</span><span class=p>,</span> <span class=p>()</span> <span class=p>=></span> <span class=p>{</span>
<span class=nx>console</span><span class=p>.</span><span class=nx>log</span><span class=p>(</span><span class=sb>`Listening on http://localhost:</span><span class=si>${</span><span class=nx>port</span><span class=si>}</span><span class=sb>`</span><span class=p>);</span>
<span class=p>});</span>
<span class=p>}</span>
<span class=k>if</span> <span class=p>(</span><span class=nx>require</span><span class=p>.</span><span class=nx>main</span> <span class=o>===</span> <span class=nx>module</span><span class=p>)</span> <span class=p>{</span>
<span class=nx>main</span><span class=p>(</span><span class=mf>6426</span><span class=p>);</span>
<span class=p>}</span>
</code></pre></div>
<p>Running this via <code>node index.js</code>, we can see what a "regular" <code>curl</code> command
returns</p>
<div class=highlight><pre><span></span><code>$ curl http://localhost:6426
Hello World!
</code></pre></div>
<p>In order to see the <strong>raw</strong> TCP response instead of the parsed HTTP response,
we can again use netcat:</p>
<div class=highlight><pre><span></span><code>$ cat request.bin | nc localhost 6426
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 13
ETag: W/"d-oLZZOWcLwsAQ9NXWoLPk5FkPuSs"
Date: Thu, 25 Feb 2021 04:47:12 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Hello World!
</code></pre></div>
<p>As with the request, we see familiar elements of an HTTP response <strong>other</strong>
than the body. For example the first line has the status code and the next
seven lines contain the headers.</p><ol class=simple-footnotes><li id=sf-http-is-just-text-1>Note that HTTP/2 is a binary protocol so this only applies
to HTTP/1.1. <a href=#sf-http-is-just-text-1-back class=simple-footnote-back>↩</a></li></ol>Broken Pipe in a Haystack2020-12-01T00:00:00-08:002020-12-01T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-12-01:/2020/12/broken-pipe.html<div style="text-align: center;">
<p><img alt="Broken Pipe" src="/images/broken-pipe.jpg"></p>
</div>
<p>I recently put on my detective hat and tracked down a bug in network error
recovery in a popular PostgreSQL library. Below, we'll walk through
the process of bugfinding and iteratively making the feedback loop smaller
and smaller. In order to find and fix the bug I</p>
<ul>
<li>Confirmed the root …</li></ul><div style="text-align: center;">
<p><img alt="Broken Pipe" src="/images/broken-pipe.jpg"></p>
</div>
<p>I recently put on my detective hat and tracked down a bug in network error
recovery in a popular PostgreSQL library. Below, we'll walk through
the process of bugfinding and iteratively making the feedback loop smaller
and smaller. In order to find and fix the bug I</p>
<ul>
<li>Confirmed the root cause of the error at the <strong>network</strong> level via
packet capture</li>
<li>Wrote a bare bones client and used a Docker container running <code>postgres</code> so
I could reproduce the behavior</li>
<li>Introduced a "know-nothing" TCP proxy in between the client and database
so I could introduce and expose networking faults to the client</li>
<li>Zoomed in on the source of the bug once the proxy enabled 100% reproducible
failure</li>
</ul>
<h3>Contents</h3>
<ul>
<li><a href=#signs-of-trouble>Signs of Trouble</a></li>
<li><a href=#confirming-a-root-cause>Confirming a Root Cause</a></li>
<li><a href=#who-is-at-fault>Who Is at Fault</a></li>
<li><a href=#synthetic-failure-via-tcp-proxy>Synthetic Failure via TCP Proxy</a></li>
<li><a href=#finding-the-bug>Finding the Bug</a></li>
<li><a href=#fixing-the-bug>Fixing the Bug</a></li>
<li><a href=#takeaways>Takeaways</a></li>
</ul>
<h3 id=signs-of-trouble>Signs of Trouble</h3>
<p>In our <code>sandbox</code> environment at Blend, there were some reports of
"broken pipe" errors showing up a few hundred times per day. Although the
<strong>error rate</strong> for this particular error was essentially zero, I was worried
this may be an issue with <a href="https://aws.amazon.com/rds/">AWS RDS</a> that may get worse, so I devoted a
half day<sup id=sf-broken-pipe-1-back><a href=#sf-broken-pipe-1 class=simple-footnote title="which later became a whole day">1</a></sup> to track it down.</p>
<p>We kept seeing log lines containing <code>write: broken pipe</code> in a few Go
microservices. For example:</p>
<div style="text-align: center;">
<p><img alt="Eleven Bad Sockets" src="/images/eleven-bad-sockets.png"></p>
</div>
<p>Since in <code>sandbox</code>, these services are often completely idle —
essentially all activity is due to end-to-end tests (E2Es) that trigger as part
of continuous deployment for related services. These broken pipe errors
appeared to occur when the services were attempting database queries after
long periods of inactivity. This was a hint that the errors were caused
by failure to gracefully manage idle connections.</p>
<h3 id=confirming-a-root-cause>Confirming a Root Cause</h3>
<p>In order to <strong>pinpoint</strong> the exact cause of the failure I decided to set up
packet capture for one of the offending services. Rather than trying to
find errors across multiple pods, the first thing I did was scale the
microservice down to one pod, being sure to remove the autoscaler in the
process:</p>
<div class=highlight><pre><span></span><code>$ kubectl delete horizontalpodautoscaler envelope-service
horizontalpodautoscaler.autoscaling "envelope-service" deleted
$
$ kubectl scale deployment/envelope-service --replicas 1
deployment.apps/envelope-service scaled
$
$ kubectl get pods --selector app=envelope-service
NAME READY STATUS RESTARTS AGE
envelope-service-bb5999898-5hb78 3/3 Terminating 0 6h4m
envelope-service-bb5999898-7r865 3/3 Running 2 18h
$
$ kubectl get pods --selector app=envelope-service
NAME READY STATUS RESTARTS AGE
envelope-service-bb5999898-7r865 3/3 Running 2 18h
</code></pre></div>
<p>From there, I pointed <code>ksniff</code> — a <code>kubectl</code> <a href="https://github.com/eldadru/ksniff">plugin</a> — at the
pod and waited until an error occurred<sup id=sf-broken-pipe-2-back><a href=#sf-broken-pipe-2 class=simple-footnote title="Note the filter only applies to port 5432, the PostgreSQL port. The .pcap file only grew to 644KiB in ninety minutes but without a filter it would've been over 1GiB.">2</a></sup>:</p>
<div class=highlight><pre><span></span><code>kubectl sniff \
envelope-service-bb5999898-7r865 \
--output-file ./ksniff-5432.pcap \
--filter "port 5432"
</code></pre></div>
<p>I captured packets in a ninety minute window and the error log
lines started showing up around forty minutes in, from <code>18:39:55</code> to <code>18:43:14</code>
UTC. In the fifteen log lines <a href=#signs-of-trouble>above</a>, there are eleven
unique client ports — <code>40288</code>, <code>40320</code>, etc. — each corresponding
to a socket from a Go <code>database/sql</code> connection pool. Viewing the packet
capture we see the AWS RDS instance sent out RST (reset) packets a few minutes
before the broken pipe errors showed up. <strong>All eleven</strong> of the sockets received
an RST around <code>18:27:09</code> UTC:</p>
<div style="text-align: center;">
<p><img alt="Eleven RST Packets" src="/images/eleven-rst-packets.png"></p>
</div>
<p>This confirmed the suspicion that the sockets had "gone bad" and that
the broken pipe errors occurred on first usage after an extended idle period.</p>
<h3 id=who-is-at-fault>Who Is at Fault</h3>
<p>A bit more about why the sockets had "gone bad". I was initially unhappy that
AWS RDS had sent RST packets, essentially hanging up the phone abruptly as
opposed to saying goodbye with a FIN packet to cleanly close the connection.
However it appears that a minute before the RST packets arrived (around
<code>18:26:09</code> UTC), the AWS RDS instance attempted to send FIN packets to each
of the idle sockets. However, the client responded with an RST from a
<strong>different</strong> port in all cases (instead of handling the FIN by responding
with a FIN / ACK):</p>
<div style="text-align: center;">
<p><img alt="RST Before (from Client)" src="/images/rst-before.png"></p>
</div>
<p>This may very well be <strong>another</strong> bug in the <code>lib/pq</code> Go library, but that is a
story for another day. I think it's more likely that this is a bug caused by
the fact that <a href="https://istio.io/">Istio</a> is managing networking in the pod via <code>iptables</code> and
there is some kind of bungled handoff happening. For example we can see that
port <code>40320</code> receives a FIN and then an RST but never sends back a FIN or RST:</p>
<div style="text-align: center;">
<p><img alt="RST to a Specific Port" src="/images/rst-port-40320.png"></p>
</div>
<h3 id=synthetic-failure-via-tcp-proxy>Synthetic Failure via TCP Proxy</h3>
<p>With reasonably high certainty that the issue was caused by
first-use-after-RST, it was time to <strong>massively</strong> decrease the size of the
feedback loop. I needed to control three moving pieces here to be able to
reproduce the conditions</p>
<ul>
<li>The Go client</li>
<li>The <code>postgres</code> server</li>
<li>The "network"</li>
</ul>
<p>In this case we don't <strong>literally</strong> need to control the network, but we
want something programmable (e.g. a proxy) so that we can send an RST without
having to reach into the blackbox of the <code>postgres</code> binary running in a Docker
container.</p>
<p>First we run the database:</p>
<div class=highlight><pre><span></span><code>docker run \
--detach \
--name pg-trigger-rst \
--hostname localhost \
--publish 13370:5432 \
--env POSTGRES_DB=superuser_db \
--env POSTGRES_USER=superuser \
--env POSTGRES_PASSWORD=password \
postgres:13.1-alpine
</code></pre></div>
<p>Next, using the <code>github.com/lib/pq</code> <a href="https://github.com/lib/pq">library</a>, the <code>broken-pipe.go</code>
<a href="/code/broken-pipe.go">script</a> creates a single connection and then executes the statement
<code>SELECT 1</code> before and after a sleep statement. During the sleep, we expect
an RST packet to be sent. In order to ensure with a high level of certainty
that the RST packet has arrived, after the first statement the script indicates
it has gone idle by writing to a (shared) state file and then sleeps for a
second before executing the second statement. If we use the script to directly
query <code>postgres</code> (i.e. without a proxy):</p>
<div class=highlight><pre><span></span><code>$ go run ./broken-pipe.go --port 13370
14:48:14.355999 Setting state to ACTIVE
14:48:14.375156 Setting state to IDLE
14:48:14.375429 Sleeping for 1 second
14:48:15.376486 Done sleeping
14:48:15.379833 Setting state to COMPLETE
</code></pre></div>
<p>The last bit here is the "network". The <code>rst-proxy.go</code> <a href="/code/rst-proxy.go">script</a> runs a
TCP proxy that <strong>usually</strong> shuttles packets between the Go client and the
<code>postgres</code> server. However, it polls the (shared) state file and once the
client has gone <code>IDLE</code> it closes the connection. In normal circumstances,
closing the connection would still not result in an RST, the kernel<sup id=sf-broken-pipe-3-back><a href=#sf-broken-pipe-3 class=simple-footnote title="This part of the socket lifecycle is not managed by Go at all, but fully by the kernel.">3</a></sup> will send a FIN to gracefully close the connection. To modify
this behavior we must set the <code>SO_LINGER</code> socket option:</p>
<div class=highlight><pre><span></span><code><span class=nx>tc</span><span class=p>,</span> <span class=nx>ok</span> <span class=o>:=</span> <span class=nx>c</span><span class=p>.(</span><span class=o>*</span><span class=nx>net</span><span class=p>.</span><span class=nx>TCPConn</span><span class=p>)</span>
<span class=c1>// ...</span>
<span class=nx>sc</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>tc</span><span class=p>.</span><span class=nx>SyscallConn</span><span class=p>()</span>
<span class=c1>// ...</span>
<span class=nx>err</span> <span class=p>=</span> <span class=nx>sc</span><span class=p>.</span><span class=nx>Control</span><span class=p>(</span><span class=kd>func</span><span class=p>(</span><span class=nx>fd</span> <span class=kt>uintptr</span><span class=p>)</span> <span class=p>{</span>
<span class=nx>syscall</span><span class=p>.</span><span class=nx>SetsockoptLinger</span><span class=p>(</span>
<span class=nb>int</span><span class=p>(</span><span class=nx>fd</span><span class=p>),</span>
<span class=nx>syscall</span><span class=p>.</span><span class=nx>SOL_SOCKET</span><span class=p>,</span>
<span class=nx>syscall</span><span class=p>.</span><span class=nx>SO_LINGER</span><span class=p>,</span>
<span class=o>&</span><span class=nx>syscall</span><span class=p>.</span><span class=nx>Linger</span><span class=p>{</span><span class=nx>Onoff</span><span class=p>:</span> <span class=mi>1</span><span class=p>,</span> <span class=nx>Linger</span><span class=p>:</span> <span class=mi>0</span><span class=p>},</span>
<span class=p>)</span>
<span class=p>})</span>
</code></pre></div>
<p>When running the <code>rst-proxy.go</code> script and pointing our client at the proxy
port, we can reproduce the error 100% of the time:</p>
<div class=highlight><pre><span></span><code>$ go run ./rst-proxy.go
14:48:18.799745 Setting up TCP proxy on localhost:23370
14:48:20.803298 Handling TCP connection from 127.0.0.1:57781
14:48:20.905144 State file switched to IDLE, closing connection
14:48:21.068089 Done proxying connection
$
$
$ # e.g. In another shell
$ go run ./broken-pipe.go --port 23370
14:48:20.800452 Setting state to ACTIVE
14:48:20.817998 Setting state to IDLE
14:48:20.818213 Sleeping for 1 second
14:48:21.818725 Done sleeping
14:48:21.818906 write tcp 127.0.0.1:57781->127.0.0.1:23370: write: broken pipe
exit status 1
</code></pre></div>
<h3 id=finding-the-bug>Finding the Bug</h3>
<p>Once I had a very small loop for reproducing the error<sup id=sf-broken-pipe-4-back><a href=#sf-broken-pipe-4 class=simple-footnote title="I could've made it smaller if I ran the proxy and the client in the same binary, but in my initial sleuthing I was using Python for the proxy because of a great StackOverflow answer that taught me about SO_LINGER.">4</a></sup> it was time
to find the source of the bug. I initially assumed that <code>database/sql</code> in Go
would "actively" manage the connection pool and remove a connection the
moment an RST was received. The fact that the error can be reproduced
100% of the time puts that theory to rest. I also did a sanity check with the
<code>pgx</code> <a href="https://github.com/jackc/pgx">library</a> and verified it <strong>does not</strong> have this bug, meaning that
this was a bug in <code>lib/pq</code>. (Despite its popularity and longevity, <code>lib/pq</code> is
in maintenance mode and the maintainers recommend using <code>pgx</code>.)</p>
<p>I wasn't sure where to look to find the bug and had zero familiarity with the
<code>lib/pq</code> codebase. So, in order zoom in on the issue I created a custom
<code>postgres-wrapped</code> database driver via the super helpful
<code>github.com/ngrok/sqlmw</code> <a href="https://github.com/ngrok/sqlmw">library</a>. In Go, a database driver is composed of
types that satisfy a small set of interfaces from <code>database/sql</code> and
<code>database/sql/driver</code>. For example the driver itself satisfies <code>driver.Driver</code>
and must have an <code>Open()</code> method that returns a connection satisfying
<code>driver.Conn</code>. Using <code>ngrok/sqlmw</code>, I was able to log every invocation of a
method from one of these interfaces, for example:</p>
<div class=highlight><pre><span></span><code><span class=kd>type</span> <span class=nx>loggingInterceptor</span> <span class=kd>struct</span> <span class=p>{</span>
<span class=nx>sqlmw</span><span class=p>.</span><span class=nx>NullInterceptor</span>
<span class=p>}</span>
<span class=kd>func</span> <span class=p>(</span><span class=o>*</span><span class=nx>loggingInterceptor</span><span class=p>)</span> <span class=nx>ConnPing</span><span class=p>(</span><span class=nx>ctx</span> <span class=nx>context</span><span class=p>.</span><span class=nx>Context</span><span class=p>,</span> <span class=nx>conn</span> <span class=nx>driver</span><span class=p>.</span><span class=nx>Pinger</span><span class=p>)</span> <span class=kt>error</span> <span class=p>{</span>
<span class=nx>log</span><span class=p>.</span><span class=nx>Println</span><span class=p>(</span><span class=s>"ConnPing() called"</span><span class=p>)</span>
<span class=k>return</span> <span class=nx>conn</span><span class=p>.</span><span class=nx>Ping</span><span class=p>(</span><span class=nx>ctx</span><span class=p>)</span>
<span class=p>}</span>
<span class=kd>func</span> <span class=p>(</span><span class=o>*</span><span class=nx>loggingInterceptor</span><span class=p>)</span> <span class=nx>ConnExecContext</span><span class=p>(</span><span class=nx>ctx</span> <span class=nx>context</span><span class=p>.</span><span class=nx>Context</span><span class=p>,</span> <span class=nx>conn</span> <span class=nx>driver</span><span class=p>.</span><span class=nx>ExecerContext</span><span class=p>,</span> <span class=nx>query</span> <span class=kt>string</span><span class=p>,</span> <span class=nx>args</span> <span class=p>[]</span><span class=nx>driver</span><span class=p>.</span><span class=nx>NamedValue</span><span class=p>)</span> <span class=p>(</span><span class=nx>driver</span><span class=p>.</span><span class=nx>Result</span><span class=p>,</span> <span class=kt>error</span><span class=p>)</span> <span class=p>{</span>
<span class=nx>log</span><span class=p>.</span><span class=nx>Println</span><span class=p>(</span><span class=s>"ConnExecContext() called"</span><span class=p>)</span>
<span class=k>return</span> <span class=nx>conn</span><span class=p>.</span><span class=nx>ExecContext</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=nx>query</span><span class=p>,</span> <span class=nx>args</span><span class=p>)</span>
<span class=p>}</span>
<span class=kd>func</span> <span class=nx>main</span><span class=p>()</span> <span class=p>{</span>
<span class=c1>// ...</span>
<span class=nx>sql</span><span class=p>.</span><span class=nx>Register</span><span class=p>(</span><span class=s>"postgres-wrapped"</span><span class=p>,</span> <span class=nx>sqlmw</span><span class=p>.</span><span class=nx>Driver</span><span class=p>(</span><span class=o>&</span><span class=nx>pq</span><span class=p>.</span><span class=nx>Driver</span><span class=p>{},</span> <span class=o>&</span><span class=nx>loggingInterceptor</span><span class=p>{}))</span>
<span class=c1>// ...</span>
<span class=nx>pool</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>sql</span><span class=p>.</span><span class=nx>Open</span><span class=p>(</span><span class=s>"postgres-wrapped"</span><span class=p>,</span> <span class=nx>dsn</span><span class=p>)</span>
<span class=c1>// ...</span>
<span class=p>}</span>
</code></pre></div>
<p>Once I was able to determine that <code>ExecContext()</code> was the source of the
<code>write: broken pipe</code>, I started to modify <code>${GOPATH}/src/github.com/lib/pq</code>
until I narrowed down the source:</p>
<ul>
<li><code>pq.conn.ExecContext</code> implements <code>driver.ExecerContext</code> (<a href="https://github.com/lib/pq/blob/v1.8.0/conn_go18.go#L32">source</a>)</li>
<li><code>pq.conn.ExecContext</code> calls <code>pq.conn.Exec</code> (<a href="https://github.com/lib/pq/blob/v1.8.0/conn_go18.go#L42">source</a>)</li>
<li><code>pq.conn.Exec</code> calls <code>pq.conn.simpleExec</code> (<a href="https://github.com/lib/pq/blob/v1.8.0/conn.go#L869">source</a>)</li>
<li><code>pq.conn.simpleExec</code> calls <code>pq.conn.send</code> (<a href="https://github.com/lib/pq/blob/v1.8.0/conn.go#L612">source</a>)</li>
<li><code>pq.conn.send</code> fails a <code>net.Conn.Write</code> with "broken pipe" and then
panics (<a href="https://github.com/lib/pq/blob/v1.8.0/conn.go#L897">source</a>)</li>
<li><code>pq.conn.errRecover</code> — invoked from <code>pq.conn.Exec</code> — handles
the <code>panic()</code> recovery (<a href="https://github.com/lib/pq/blob/v1.8.0/conn.go#L863">source</a>)</li>
<li><code>pq.conn.errRecover</code> handles a <code>*net.OpError</code> by setting the <code>bad</code> flag to
tombstone the connection but just returns the error as-is (<a href="https://github.com/lib/pq/blob/v1.8.0/error.go#L495-L497">source</a>)</li>
</ul>
<p>I must say I was surprised by this, using <code>panic()</code> / <code>recover()</code> essentially
amounts to <code>try / except</code> in other languages, a pattern that is not very
common in Go<sup id=sf-broken-pipe-5-back><a href=#sf-broken-pipe-5 class=simple-footnote title="and one that carries with it the cost of stack unwinding">5</a></sup>.</p>
<h3 id=fixing-the-bug>Fixing the Bug</h3>
<p>Luckily I was able to submit a fix (<a href="https://github.com/lib/pq/pull/1013">lib/pq#1013</a>) that was small and
easy to reason about. This likely contributed to the quick review and merge
from the <code>lib/pq</code> maintainers. The fix was to explicitly mark the error
as <strong>safe to retry</strong> when we know zero bytes were written and then to return
the <code>driver.ErrBadConn</code> sentinel to signal to <code>database/sql</code> that the
connection should be removed from the pool:</p>
<div class=highlight><pre><span></span><code><span class=gh>diff --git a/conn.go b/conn.go</span>
<span class=gh>index f313c14..0d96600 100644</span>
<span class=gd>--- a/conn.go</span>
<span class=gi>+++ b/conn.go</span>
<span class=gu>@@ -891,9 +891,20 @@ func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err</span>
return r, err
}
<span class=gi>+type safeRetryError struct {</span>
<span class=gi>+ Err error</span>
<span class=gi>+}</span>
<span class=gi>+</span>
<span class=gi>+func (se *safeRetryError) Error() string {</span>
<span class=gi>+ return se.Err.Error()</span>
<span class=gi>+}</span>
<span class=gi>+</span>
func (cn *conn) send(m *writeBuf) {
<span class=gd>- _, err := cn.c.Write(m.wrap())</span>
<span class=gi>+ n, err := cn.c.Write(m.wrap())</span>
if err != nil {
<span class=gi>+ if n == 0 {</span>
<span class=gi>+ err = &safeRetryError{Err: err}</span>
<span class=gi>+ }</span>
panic(err)
}
}
<span class=gh>diff --git a/error.go b/error.go</span>
<span class=gh>index 3d66ba7..a227e08 100644</span>
<span class=gd>--- a/error.go</span>
<span class=gi>+++ b/error.go</span>
<span class=gu>@@ -495,6 +495,9 @@ func (cn *conn) errRecover(err *error) {</span>
case *net.OpError:
cn.bad = true
*err = v
<span class=gi>+ case *safeRetryError:</span>
<span class=gi>+ cn.bad = true</span>
<span class=gi>+ *err = driver.ErrBadConn</span>
case error:
if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
*err = driver.ErrBadConn
</code></pre></div>
<p>I certainly didn't come up with this idea on my own. I previously mentioned
that <code>pgx</code> did <strong>not</strong> have the same bug. When vetting <code>pgx</code>, I dug through
the source in the same way that I did with <code>lib/pq</code> and found that
<code>PgConn.Exec()</code> <a href="https://github.com/jackc/pgconn/blob/v1.7.2/pgconn.go#L923">marks</a> an error as safe when exactly zero bytes are
written and the high-level driver connection returns the sentinel
<code>driver.ErrBadConn</code> if an error is <a href="https://github.com/jackc/pgx/blob/v4.9.2/stdlib/sql.go#L336-L337">safe to retry</a>.</p>
<h3 id=takeaways>Takeaways</h3>
<p>In some sense, we should've never been down this road because <code>lib/pq</code> is in
maintenance mode. However, the real story here is about starting from a
wide open view of microservice logs and narrowing down all the way to a line
of library code. Additionally, the story may not be over if the RST packets are
caused by a connection handoff issue with <a href="https://istio.io/">Istio</a>.</p>
<p>So what should a reader take away from this long and winding road to a bugfix?</p>
<ul>
<li>A first lesson in tight feedback loops: ensure the code being debugged
is running in a controlled environment. Here that meant scaling the
Kubernetes deployment down to one pod</li>
<li>Networking bugs are not so scary, packet capture coupled with logs
and Wireshark's helpful UI quickly told the story</li>
<li>Another lesson in tight feedback loops: once the RST hypothesis was
confirmed, <strong>control the whole stack</strong>. Throw away as many confounding
factors as possible and just focus in on the problem area. Strongly prefer
reproducible examples that can be run on your development machine (i.e. a
develop, deploy, debug loop is not tight enough).</li>
<li>Treat components as a black box when beneficial. Figuring out in fine
detail how to make <code>postgres</code> send the RST could've taken a <strong>very</strong> long
time, so we took the shorter path by putting a proxy in front of
<code>postgres</code> that we could fully control.</li>
<li>Had we used the recommended <code>pgx</code>, there would have been no bug to fix;
upgrade dependencies early and often and look out for deprecation notices
like the one in <code>lib/pq</code></li>
</ul>
<hr style="margin-bottom: 25px; width: 50%;"><ol class=simple-footnotes><li id=sf-broken-pipe-1>which later became a whole day <a href=#sf-broken-pipe-1-back class=simple-footnote-back>↩</a></li><li id=sf-broken-pipe-2>Note the filter only applies to
port 5432, the PostgreSQL port. The <code>.pcap</code> file only grew to 644KiB in
ninety minutes but without a filter it would've been over 1GiB. <a href=#sf-broken-pipe-2-back class=simple-footnote-back>↩</a></li><li id=sf-broken-pipe-3>This
part of the socket lifecycle is not managed by Go at all, but fully by the
kernel. <a href=#sf-broken-pipe-3-back class=simple-footnote-back>↩</a></li><li id=sf-broken-pipe-4>I could've made it
smaller if I ran the proxy and the client in the same binary, but in my
initial sleuthing I was using Python for the proxy because of a great
StackOverflow <a href="https://stackoverflow.com/a/6440364/1068170">answer</a> that taught me about <code>SO_LINGER</code>. <a href=#sf-broken-pipe-4-back class=simple-footnote-back>↩</a></li><li id=sf-broken-pipe-5>and one that carries with it the cost of stack
unwinding <a href=#sf-broken-pipe-5-back class=simple-footnote-back>↩</a></li></ol>pow Confusion2020-11-25T00:00:00-08:002020-11-25T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-11-25:/2020/11/pow-confusion.html<p>In my first summer of graduate school my code suddenly stopped working
because Fortran and Python (via <code>pow()</code> in C) do exponentiation differently.
Once I debugged and understood the problem, I learned about the highly
optimized assembly code produced by Fortran for integer exponents.</p>
<p>To give a sample of the …</p><p>In my first summer of graduate school my code suddenly stopped working
because Fortran and Python (via <code>pow()</code> in C) do exponentiation differently.
Once I debugged and understood the problem, I learned about the highly
optimized assembly code produced by Fortran for integer exponents.</p>
<p>To give a sample of the tool I wrote, here is an analysis of the assembly
generated by the <code>gfortran</code> compiler for <code>b = a**5</code>:</p>
<div class=highlight><pre><span></span><code>$ python ./describe_assembly.py --exponent 5
+-------------------------+------------+
| %xmm0[:64] | %xmm1[:64] |
+-------------------------+------------+
| a | | f2 0f 10 07 movsd [(%rdi), %xmm0 ]
| a | a | 66 0f 28 c8 movapd [ %xmm0, %xmm1 ]
| a | a * a | f2 0f 59 c8 mulsd [ %xmm0, %xmm1 ]
| (a * a) * a | a * a | f2 0f 59 c1 mulsd [ %xmm1, %xmm0 ]
| (a * a) * ((a * a) * a) | a * a | f2 0f 59 c1 mulsd [ %xmm1, %xmm0 ]
| b | | f2 0f 11 06 movsd [ %xmm0, (%rsi)]
+-------------------------+------------+
</code></pre></div>
<h3>Contents</h3>
<ul>
<li><a href=#motivation>Motivation</a></li>
<li><a href=#difference>What's the Difference?</a></li>
<li><a href=#fortran-algorithm>Fortran's Nifty Algorithm</a></li>
<li><a href=#assembly>I Don't Speak Assembly</a></li>
</ul>
<h3 id=motivation>Motivation</h3>
<p>In my first summer of graduate school, I had a very productive June. I was
working on a research project<sup id=sf-pow-confusion-1-back><a href=#sf-pow-confusion-1 class=simple-footnote title="The project unfortunately never led to results that could be published.">1</a></sup> on optimization of triangular meshes for
compression and storage. A core part of this involved taking fourth powers of
floating point numbers<sup id=sf-pow-confusion-2-back><a href=#sf-pow-confusion-2 class=simple-footnote title="I.e., values of type double in C">2</a></sup>. Once I
reached a point where my slow Python code worked well enough, I started porting
to Fortran 95. I foolishly expected bit-for-bit identical behavior but instead
the changes — which I later learned were exclusively from the fourth
power operation — were so dramatic I lost a <strong>full week</strong> of productivity
debugging the existing test cases.</p>
<p>As with most optimization problems, this involved applying
<a href="https://en.wikipedia.org/wiki/Gradient_descent">gradient descent</a><sup id=sf-pow-confusion-3-back><a href=#sf-pow-confusion-3 class=simple-footnote title="and related algorithms">3</a></sup> to a number of
handpicked objective functions. Since this involved triangles and compression,
we were trying to modify the mesh<sup id=sf-pow-confusion-4-back><a href=#sf-pow-confusion-4 class=simple-footnote title="It's worth noting that for our purposes a trianglular mesh is just a collection of triangles that share edges, so if one triangle changes, the neighboring triangles must as well.">4</a></sup> by
"binning" triangles into similar shapes. For our early objective functions,
this could lead to flattened out triangles that looked more like lines than
triangles. Luckily there <a href="https://doi.org/10.1090/S0025-5718-03-01485-6">exist</a> a number of ways to measure the "quality"
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span></span> of a triangle as a number between <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn></mrow><annotation encoding="application/x-tex">0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>0</span></span></span></span> and
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.64444em;vertical-align:0em;></span><span class=mord>1</span></span></span></span>; a very low quality corresponds exactly
to this flatness. To penalize low-quality triangles we included functions of
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant=normal>/</mi><mi>q</mi></mrow><annotation encoding="application/x-tex">1 / q</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mord>1/</span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span></span> in our objective functions and several of the most
successful used a loop over all triangles <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.13889em;>T</span></span></span></span> in the mesh
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant=script>M</mi></mrow><annotation encoding="application/x-tex">\mathcal{M}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathcal">M</span></span></span></span></p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><munder><mo>∑</mo><mrow><mi>T</mi><mo>∈</mo><mi mathvariant=script>M</mi></mrow></munder><mfrac><mn>1</mn><mrow><mi>q</mi><mo stretchy=false>(</mo><mi>T</mi><msup><mo stretchy=false>)</mo><mn>4</mn></msup></mrow></mfrac></mrow><annotation encoding="application/x-tex">\sum_{T \in \mathcal{M}} \frac{1}{q(T)^4}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:2.6431459999999998em;vertical-align:-1.321706em;></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.050005em;><span style=top:-1.8556639999999998em;margin-left:0em;><span class=pstrut style=height:3.05em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.13889em;>T</span><span class="mrel mtight">∈</span><span class="mord mathcal mtight">M</span></span></span></span><span style=top:-3.0500049999999996em;><span class=pstrut style=height:3.05em;></span><span><span class="mop op-symbol large-op">∑</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.321706em;><span></span></span></span></span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.13889em;>T</span><span class=mclose><span class=mclose>)</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.740108em;><span style=top:-2.9890000000000003em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.936em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<h3 id=difference>What's the Difference?</h3>
<p>When the exponent <code>n</code> is an integer, Fortran <code>x**n</code> behaves
much differently than Python. In Fortran, optimized assembly is generated to
minimize the number of multiplications, whereas Python calls out to <code>pow()</code>
from <code>math.h</code> in C. Compare an explicit vs. implicit implementation in Python:</p>
<div class=highlight><pre><span></span><code><span class=k>def</span> <span class=nf>fourth_explicit</span><span class=p>(</span><span class=n>value</span><span class=p>):</span>
<span class=n>squared</span> <span class=o>=</span> <span class=n>value</span> <span class=o>*</span> <span class=n>value</span>
<span class=k>return</span> <span class=n>squared</span> <span class=o>*</span> <span class=n>squared</span>
<span class=k>def</span> <span class=nf>fourth_pow</span><span class=p>(</span><span class=n>value</span><span class=p>):</span>
<span class=k>return</span> <span class=n>value</span> <span class=o>**</span> <span class=mi>4</span>
</code></pre></div>
<p>For well-behaved values, these two functions compute
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant=normal>/</mi><msup><mi>q</mi><mn>4</mn></msup></mrow><annotation encoding="application/x-tex">1 / q^4</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.064108em;vertical-align:-0.25em;></span><span class=mord>1/</span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span></span> without much difference</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=mi>1</span> <span class=o>/</span> <span class=n>fourth_explicit</span><span class=p>(</span><span class=mf>0.25</span><span class=p>)</span>
<span class=mf>256.0</span>
<span class=o>>>></span> <span class=mi>1</span> <span class=o>/</span> <span class=n>fourth_pow</span><span class=p>(</span><span class=mf>0.25</span><span class=p>)</span>
<span class=mf>256.0</span>
<span class=o>>>></span> <span class=n>quality</span> <span class=o>=</span> <span class=mf>0.2689565746627065</span>
<span class=o>>>></span> <span class=mi>1</span> <span class=o>/</span> <span class=n>fourth_explicit</span><span class=p>(</span><span class=n>quality</span><span class=p>)</span>
<span class=mf>191.1046874202122</span>
<span class=o>>>></span> <span class=mi>1</span> <span class=o>/</span> <span class=n>fourth_pow</span><span class=p>(</span><span class=n>quality</span><span class=p>)</span>
<span class=mf>191.10468742021223</span>
</code></pre></div>
<p>however when <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>q</mi></mrow><annotation encoding="application/x-tex">q</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.19444em;></span><span class="mord mathnormal" style=margin-right:0.03588em;>q</span></span></span></span> becomes small (the type of values we are
penalizing) the magnitude of <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mi mathvariant=normal>/</mi><msup><mi>q</mi><mn>4</mn></msup></mrow><annotation encoding="application/x-tex">1 / q^4</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.064108em;vertical-align:-0.25em;></span><span class=mord>1/</span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em;>q</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span></span> means that small
relative differences are still large absolute differences in our objective
function:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>quality</span> <span class=o>=</span> <span class=mf>2.3824755061912883e-06</span>
<span class=o>>>></span> <span class=mi>1</span> <span class=o>/</span> <span class=n>fourth_explicit</span><span class=p>(</span><span class=n>quality</span><span class=p>)</span>
<span class=mf>3.103746353229757e+22</span>
<span class=o>>>></span> <span class=mi>1</span> <span class=o>/</span> <span class=n>fourth_pow</span><span class=p>(</span><span class=n>quality</span><span class=p>)</span>
<span class=mf>3.103746353229758e+22</span>
<span class=o>>>></span>
<span class=o>>>></span> <span class=mi>1</span> <span class=o>/</span> <span class=n>fourth_explicit</span><span class=p>(</span><span class=n>quality</span><span class=p>)</span> <span class=o>-</span> <span class=mi>1</span> <span class=o>/</span> <span class=n>fourth_pow</span><span class=p>(</span><span class=n>quality</span><span class=p>)</span>
<span class=o>-</span><span class=mf>8388608.0</span>
</code></pre></div>
<p>The difference is caused by the fact that <code>pow()</code> treats everything like a
floating point number and uses <code>exp()</code>, <code>log()</code> and multiplication via</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msup><mi>x</mi><mi>y</mi></msup><mo>=</mo><msup><mi>e</mi><mrow><mi>y</mi><mi>log</mi><mo></mo><mo stretchy=false>(</mo><mi>x</mi><mo stretchy=false>)</mo></mrow></msup><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">x^y = e^{y \log(x)}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.714392em;vertical-align:0em;></span><span class=mord><span class="mord mathnormal">x</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.714392em;><span style=top:-3.1130000000000004em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style=margin-right:0.03588em;>y</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.938em;vertical-align:0em;></span><span class=mord><span class="mord mathnormal">e</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.938em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.03588em;>y</span><span class="mspace mtight" style=margin-right:0.19516666666666668em;></span><span class="mop mtight"><span class=mtight>l</span><span class=mtight>o</span><span class=mtight style=margin-right:0.01389em;>g</span></span><span class="mopen mtight">(</span><span class="mord mathnormal mtight">x</span><span class="mclose mtight">)</span></span></span></span></span></span></span></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<h3 id=fortran-algorithm>Fortran's Nifty Algorithm</h3>
<p>Breaking down the <a href="https://godbolt.org/z/eq6MGh">assembly</a> for <code>b = a**4</code> in Fortran we see the repeated
squaring</p>
<div class=highlight><pre><span></span><code><span class=nl>pow4:</span>
<span class=nf>movsd</span> <span class=no>xmm0</span><span class=p>,</span> <span class=no>QWORD</span> <span class=no>PTR</span> <span class=p>[</span><span class=no>rdi</span><span class=p>]</span>
<span class=nf>mulsd</span> <span class=no>xmm0</span><span class=p>,</span> <span class=no>xmm0</span>
<span class=nf>mulsd</span> <span class=no>xmm0</span><span class=p>,</span> <span class=no>xmm0</span>
<span class=nf>movsd</span> <span class=no>QWORD</span> <span class=no>PTR</span> <span class=p>[</span><span class=no>rsi</span><span class=p>],</span> <span class=no>xmm0</span>
<span class=nf>ret</span>
</code></pre></div>
<p>as compared to a jump (<code>jmp</code>) instruction <a href="https://godbolt.org/z/b5nYed">in C</a></p>
<div class=highlight><pre><span></span><code><span class=nl>pow4:</span>
<span class=nf>movsd</span> <span class=no>xmm1</span><span class=p>,</span> <span class=no>QWORD</span> <span class=no>PTR</span> <span class=no>.LC0</span><span class=p>[</span><span class=no>rip</span><span class=p>]</span>
<span class=nf>jmp</span> <span class=no>pow</span>
<span class=nl>.LC0:</span>
<span class=na>.long</span> <span class=mi>0</span>
<span class=na>.long</span> <span class=mi>1074790400</span>
</code></pre></div>
<p>Similarly for <code>q**7</code> the assembly <a href="https://godbolt.org/z/f7EPWP">shows</a> only multiplications (vs. a <code>jmp</code>)</p>
<div class=highlight><pre><span></span><code><span class=nl>pow7:</span>
<span class=nf>movsd</span> <span class=no>xmm0</span><span class=p>,</span> <span class=no>QWORD</span> <span class=no>PTR</span> <span class=p>[</span><span class=no>rdi</span><span class=p>]</span>
<span class=nf>movapd</span> <span class=no>xmm1</span><span class=p>,</span> <span class=no>xmm0</span>
<span class=nf>mulsd</span> <span class=no>xmm1</span><span class=p>,</span> <span class=no>xmm0</span>
<span class=nf>mulsd</span> <span class=no>xmm0</span><span class=p>,</span> <span class=no>xmm1</span>
<span class=nf>mulsd</span> <span class=no>xmm1</span><span class=p>,</span> <span class=no>xmm1</span>
<span class=nf>mulsd</span> <span class=no>xmm0</span><span class=p>,</span> <span class=no>xmm1</span>
<span class=nf>movsd</span> <span class=no>QWORD</span> <span class=no>PTR</span> <span class=p>[</span><span class=no>rsi</span><span class=p>],</span> <span class=no>xmm0</span>
<span class=nf>ret</span>
</code></pre></div>
<h3 id=assembly>I Don't Speak Assembly</h3>
<p>Like most professional software engineers (and science PhDs who write code) I
have no formal training, so reading assembly is something I've never done.
So I wrote a <a href="/code/describe_assembly.py">script</a> to generate a Fortran subroutine that computes
<code>b = a**n</code> for a fixed value of <code>n</code>, compiles the code to an object file
and then disassembles it. For example:</p>
<div class=highlight><pre><span></span><code>$ gfortran -c -O3 ./pow7.f90 -o ./pow7.o -J ./
$ objdump --disassemble ./pow7.o
</code></pre></div>
<p>However, these instructions are still hard to visualize so I parsed the
disassembled instructions from the object file and tracked all of the
active registers (<code>%xmm{N}</code>) as they were updated. In addition to the <code>xmm</code>
registers, the <code>%rsi</code> (source) and <code>%rdi</code> (destination) registers are used
for copying data <strong>from</strong> <code>a</code> and <strong>to</strong> <code>b</code> after the computation is done.</p>
<p>Being able to visualize this really helped! For <code>n = 4</code> we can see the
generated assembly is efficient enough that it only requires one register</p>
<div class=highlight><pre><span></span><code>$ python ./describe_assembly.py --exponent 4
+-------------------+
| %xmm0[:64] |
+-------------------+
| a | f2 0f 10 07 movsd [(%rdi), %xmm0 ]
| a * a | f2 0f 59 c0 mulsd [ %xmm0, %xmm0 ]
| (a * a) * (a * a) | f2 0f 59 c0 mulsd [ %xmm0, %xmm0 ]
| b | f2 0f 11 06 movsd [ %xmm0, (%rsi)]
+-------------------+
</code></pre></div>
<p>and <code>n = 7</code> can do all of its work in two registers</p>
<div class=highlight><pre><span></span><code>$ python ./describe_assembly.py --exponent 7
+-------------------------------------+-------------------+
| %xmm0[:64] | %xmm1[:64] |
+-------------------------------------+-------------------+
| a | | f2 0f 10 07 movsd [(%rdi), %xmm0 ]
| a | a | 66 0f 28 c8 movapd [ %xmm0, %xmm1 ]
| a | a * a | f2 0f 59 c8 mulsd [ %xmm0, %xmm1 ]
| (a * a) * a | a * a | f2 0f 59 c1 mulsd [ %xmm1, %xmm0 ]
| (a * a) * a | (a * a) * (a * a) | f2 0f 59 c9 mulsd [ %xmm1, %xmm1 ]
| ((a * a) * (a * a)) * ((a * a) * a) | (a * a) * (a * a) | f2 0f 59 c1 mulsd [ %xmm1, %xmm0 ]
| b | | f2 0f 11 06 movsd [ %xmm0, (%rsi)]
+-------------------------------------+-------------------+
</code></pre></div>
<blockquote>
<p><strong>PS</strong>: It's worth noting here that black box analysis of the generated
assembly is not the only way to understand what <code>gfortran</code> will do. I
attempted to dive into the source for <code>gfortran</code> to understand exactly how
this is generated (in particular if it differs when the exponent <code>n</code> is not
known until runtime). However, I was not able to find any conclusive section
of code responsible and ran out of time digging.</p>
</blockquote><ol class=simple-footnotes><li id=sf-pow-confusion-1>The project unfortunately never led to
results that could be published. <a href=#sf-pow-confusion-1-back class=simple-footnote-back>↩</a></li><li id=sf-pow-confusion-2>I.e., values of type <code>double</code> in C <a href=#sf-pow-confusion-2-back class=simple-footnote-back>↩</a></li><li id=sf-pow-confusion-3>and related algorithms <a href=#sf-pow-confusion-3-back class=simple-footnote-back>↩</a></li><li id=sf-pow-confusion-4>It's worth noting that for our purposes a
<a href="https://en.wikipedia.org/wiki/Triangle_mesh">trianglular mesh</a> is just a collection of triangles that share edges, so if
one triangle changes, the neighboring triangles must as well. <a href=#sf-pow-confusion-4-back class=simple-footnote-back>↩</a></li></ol>Running dd-agent Locally2020-09-28T00:00:00-07:002020-09-28T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-09-28:/2020/09/local-dd-agent.html<blockquote>
<p><strong>TL;DR</strong>: Running Datadog (<code>dd-agent</code>) during local development can help
confirm metrics and traces are sent as expected and can help debug when things
go wrong. To run <code>dd-agent</code> locally just clone the
<a href="https://github.com/dhermes/local-dd-agent">dhermes/local-dd-agent</a><sup id=sf-local-dd-agent-1-back><a href=#sf-local-dd-agent-1 class=simple-footnote title="As of b5b577154c7bf2c80020a0d87aa3c111e7cead8c">1</a></sup> repository and <code>make run</code>.</p>
<p>Being able to quickly iterate with a local <code>dd-agent</code> helped …</p></blockquote><blockquote>
<p><strong>TL;DR</strong>: Running Datadog (<code>dd-agent</code>) during local development can help
confirm metrics and traces are sent as expected and can help debug when things
go wrong. To run <code>dd-agent</code> locally just clone the
<a href="https://github.com/dhermes/local-dd-agent">dhermes/local-dd-agent</a><sup id=sf-local-dd-agent-1-back><a href=#sf-local-dd-agent-1 class=simple-footnote title="As of b5b577154c7bf2c80020a0d87aa3c111e7cead8c">1</a></sup> repository and <code>make run</code>.</p>
<p>Being able to quickly iterate with a local <code>dd-agent</code> helped to quickly
locate bugfixes <a href="https://github.com/brightcove/hot-shots/pull/189">brightcove/hot-shots#189</a>.</p>
</blockquote>
<h3>Motivation</h3>
<p>During local development, we often just turn off code that sends metrics and
traces to <code>datadog</code>. We just trust that our application metrics and traces will
work as expected when deployed to environments (e.g. Kubernetes) where
<code>dd-agent</code> is running.</p>
<p>This is especially challenging when things <strong>go wrong</strong>. For example, sometimes
a task will exit before flushing all metrics out to <code>dd-agent</code> and debugging
an application in Kubernetes is a much larger challenge than debugging it
on a development machine.</p>
<p>I was recently debugging a critical production issue caused by a bug in the
connection error recovery<sup id=sf-local-dd-agent-2-back><a href=#sf-local-dd-agent-2 class=simple-footnote title="In particular, this was for errors caused by a failed connection to a Unix Domain Socket (UDS) usually available at /var/run/datadog/dsd.socket.">2</a></sup> code in <code>hot-shots</code>. (At Blend we use
<code>hot-shots</code>, a popular open source library, as a base for connecting to Datadog
in all<sup id=sf-local-dd-agent-3-back><a href=#sf-local-dd-agent-3 class=simple-footnote title="Maybe not all? But most.">3</a></sup> Node.js applications.) By running
<code>dd-agent</code> locally, I was able to reproduce the bug and with a tight feedback
loop track down three more <a href="https://github.com/brightcove/hot-shots/issues/128#issuecomment-699046970">problems</a> with the implementation. This led to a
<a href="https://github.com/brightcove/hot-shots/pull/189">fix</a> as well so we can properly recover from connection errors.</p>
<h3>Running <code>dd-agent</code></h3>
<p>To run the <code>dd-agent</code> locally, clone <code>local-dd-agent</code> and build the Docker
container for the <code>dd-agent</code> application</p>
<div class=highlight><pre><span></span><code>git clone git@github.com:dhermes/local-dd-agent.git
cd local-dd-agent/
make build
</code></pre></div>
<p>then run the container via</p>
<div class=highlight><pre><span></span><code>make run
# OR:
# make run DATADOG_ADDRESS=".../custom/path/to/dsd.socket"
</code></pre></div>
<p>The start logs<sup id=sf-local-dd-agent-4-back><a href=#sf-local-dd-agent-4 class=simple-footnote title="The container runs a UDP listener on port 8125 for metrics, a TCP listener on port 8126 for traces, a UDS listener at /var/run/datadog/dsd.socket in the container and a UDS listener at $(pwd)/var-run-datadog/dsd.socket on the host (i.e. the machine that invoked docker run).">4</a></sup> should resemble:</p>
<div style="text-align: center;">
<p><img alt="Local dd-agent Start" src="/images/local-dd-agent-start.png"></p>
</div>
<p>Triggering some requests to a sample application,
we'd see example logs to the agent like:</p>
<div style="text-align: center;">
<p><img alt="Example Logs from Local dd-agent" src="/images/local-dd-agent.png"></p>
</div>
<h4>Common Testing Actions</h4>
<p>After running an application (e.g. on port 10034) it will be useful to send
a "bare" request</p>
<div class=highlight><pre><span></span><code>curl http://localhost:10034
</code></pre></div>
<p>as well as a request that's part of a trace that has been opened in an
upstream application</p>
<div class=highlight><pre><span></span><code>curl \
--header 'x-datadog-trace-id: 3131313131313131313' \
--header 'x-datadog-parent-id: 4747474747474747474' \
http://localhost:10034
</code></pre></div>
<p>To compare to the "no <code>dd-agent</code>" experience, it's helpful to utilize an
environment variable (e.g. <code>DATADOG_DISABLE</code>) to easily disable the metrics
collector from emitting anything (i.e. make sure nothing gets sent out on port
8125 to the <code>local-dd-agent</code> UDP metrics listener).</p>
<p>Similar, having an environment variable (e.g. <code>DATADOG_TRACE_DEBUG_MODE</code>) can
be quite helpful to put tracing in debug mode (e.g. to debug if the trace
server on port 8126 can't be reached or APM responses are invalid):</p>
<div class=highlight><pre><span></span><code>DATADOG_TRACE_DEBUG_MODE=true npm start
# {"message":"Server listening on port 10034","level":"info","dd":{"trace_id":"4552692657769386461","span_id":"4552692657769386461","service":"dd-sanity-check","env":"dev"},"_timestamp":"2020-09-28T14:29:49.959Z"}
# Encoding trace: [{"trace_id":"3f2e69d9dddf91dd","span_id":"3f2e69d9dddf91dd","parent_id":"0000000000000000","name":"serverInit","resource":"serverInit","error":0,"meta":{"service":"dd-sanity-check","env":"dev","version":"","language":"javascript"},"metrics":{"_sample_rate":1,"_dd.agent_psr":1,"_sampling_priority_v1":1},"start":1601303389949310200,"duration":12327637,"service":"dd-sanity-check"}]
# Added encoded trace to buffer: 91 8b a8 74 72 61 63 65 5f 69 64 cf 3f 2e 69 d9 dd df 91 dd a7 73 70 61 6e 5f 69 64 cf 3f 2e 69 d9 dd df 91 dd a5 73 74 61 72 74 d3 16 38 f8 f2 f7 8e b5 00 a8 64 75 72 61 74 69 6f 6e d3 00 00 00 00 00 bc 1a d5 a5 65 72 72 6f 72 00 a9 70 61 72 65 6e 74 5f 69 64 cf 00 00 00 00 00 00 00 00 a4 6e 61 6d 65 aa 73 65 72 76 65 72 49 6e 69 74 a8 72 65 73 6f 75 72 63 65 aa 73 65 72 76 65 72 49 6e 69 74 a7 73 65 72 76 69 63 65 af 64 64 2d 73 61 6e 69 74 79 2d 63 68 65 63 6b a4 6d 65 74 61 84 a7 73 65 72 76 69 63 65 af 64 64 2d 73 61 6e 69 74 79 2d 63 68 65 63 6b a3 65 6e 76 a3 64 65 76 a7 76 65 72 73 69 6f 6e a0 a8 6c 61 6e 67 75 61 67 65 aa 6a 61 76 61 73 63 72 69 70 74 a7 6d 65 74 72 69 63 73 83 ac 5f 73 61 6d 70 6c 65 5f 72 61 74 65 cb 3f f0 00 00 00 00 00 00 ad 5f 64 64 2e 61 67 65 6e 74 5f 70 73 72 cb 3f f0 00 00 00 00 00 00 b5 5f 73 61 6d 70 6c 69 6e 67 5f 70 72 69 6f 72 69 74 79 5f 76 31 cb 3f f0 00 00 00 00 00 00
# Request to the agent: {"path":"/v0.4/traces","method":"PUT","headers":{"Content-Type":"application/msgpack","Datadog-Meta-Tracer-Version":"0.20.3","X-Datadog-Trace-Count":"1","Datadog-Meta-Lang":"nodejs","Datadog-Meta-Lang-Version":"v12.18.3","Datadog-Meta-Lang-Interpreter":"v8"},"protocol":"http:","hostname":"localhost","port":"8126"}
# Response from the agent: {}
</code></pre></div>
<h3>Caveats</h3>
<p>The code in <code>local-dd-agent</code> is completely handwritten and is a best effort
to map to Datadog features. There are <strong>known</strong> features not yet implemented
(e.g. parsing of <code>_e{}</code> / Event metric datagrams) and likely <strong>unknown</strong>
bugs or missing features (e.g. future API versions for APM).</p>
<p>If it doesn't work as expected, please let me know and I'll be happy to
help fix bugs, advise on how to extend and do anything else to resolve.</p><ol class=simple-footnotes><li id=sf-local-dd-agent-1>As of
<code>b5b577154c7bf2c80020a0d87aa3c111e7cead8c</code> <a href=#sf-local-dd-agent-1-back class=simple-footnote-back>↩</a></li><li id=sf-local-dd-agent-2>In particular, this was for errors caused by a
failed connection to a Unix Domain Socket (UDS) usually available at
<code>/var/run/datadog/dsd.socket</code>. <a href=#sf-local-dd-agent-2-back class=simple-footnote-back>↩</a></li><li id=sf-local-dd-agent-3>Maybe not all? But most. <a href=#sf-local-dd-agent-3-back class=simple-footnote-back>↩</a></li><li id=sf-local-dd-agent-4>The container runs a UDP listener on port 8125 for metrics,
a TCP listener on port 8126 for traces, a UDS listener at
<code>/var/run/datadog/dsd.socket</code> in the container and a UDS listener at
<code>$(pwd)/var-run-datadog/dsd.socket</code> on the host (i.e. the machine that
invoked <code>docker run</code>). <a href=#sf-local-dd-agent-4-back class=simple-footnote-back>↩</a></li></ol>Reading Istio Secrets2020-09-04T00:00:00-07:002020-09-04T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-09-04:/2020/09/istio-workload-secrets.html<p>Adopting a service mesh like Istio is a <strong>huge</strong> undertaking. (Let's set aside
for this discussion whether it's a <a href="https://twitter.com/rakyll/status/1173663473357574144">good idea</a> to undertake.) A fairly
common issue when getting a mesh up and running is misconfiguration. When
trying to debug and determine where and how things are misconfigured, the
network …</p><p>Adopting a service mesh like Istio is a <strong>huge</strong> undertaking. (Let's set aside
for this discussion whether it's a <a href="https://twitter.com/rakyll/status/1173663473357574144">good idea</a> to undertake.) A fairly
common issue when getting a mesh up and running is misconfiguration. When
trying to debug and determine where and how things are misconfigured, the
network is usually not an ally.</p>
<p><img alt=Istio src="/images/istio-whitelogo-bluebackground-framed.svg"></p>
<h3>The Plan</h3>
<p>A common option when "the network is broken" and we're flying blind is to use
a packet sniffer to debug. On a development machine, that'd probably be
<a href="https://www.wireshark.org/">Wireshark</a>. In Kubernetes, <code>ksniff</code> is a popular <a href="https://github.com/eldadru/ksniff">tool</a> to capture
packets and send them back to a development machine for inspection. However,
when the connections are encrypted with TLS, captured packets are not so
useful. For "modern" TLS connections, Wireshark requires a client random data
for the session (see <code>SSLKEYLOGFILE</code>) and the private key that encrypted the
traffic.</p>
<p>In this post, we'll be grabbing the private key from a Kubernetes container
in an Istio service mesh to aid in a debugging process. This is something a
cluster administrator would be doing, not an every day thing and not something
a "service owner" would be expected to do. I am writing this up because I
was frustrated by lack of materials found when searching how to do this.</p>
<h3>Envoy and Existing Support</h3>
<p>Kubernetes containers in the Istio service mesh run a sidecar container with
Envoy proxy running. In most cases, this sidecar runs in <code>iptables</code> mode.
In this mode, it tells the Linux kernel (via <code>iptables</code>) that Envoy will be
handling all<sup id=sf-istio-workload-secrets-1-back><a href=#sf-istio-workload-secrets-1 class=simple-footnote title="Not all, really most">1</a></sup> network traffic in the
pod. In other words, Envoy has <strong>full control</strong> of the network for any workload
it is running next to as a sidecar.</p>
<p>The Envoy <a href="https://www.envoyproxy.io/docs/envoy/latest/operations/traffic_tapping">traffic tap</a> feature exists for capturing potentially encrypted
packets in a <code>.pcap</code> file<sup id=sf-istio-workload-secrets-2-back><a href=#sf-istio-workload-secrets-2 class=simple-footnote title="The file format used by Wireshark and tcpdump">2</a></sup>. See the
<a href="https://medium.com/@mtchkll/solving-microservice-mysteries-with-envoys-tap-filter-fd159c36d0af">Solving Microservice Mysteries With Envoy's Tap Filter</a> for a pretty great
explainer on using traffic tap.</p>
<p>It would be perfectly fine to just stop here and say "use traffic tap".
However, I kept pulling the thread. At the end of the day, traffic tap is
white box / clear box debugging into the <strong>known</strong> behavior of Envoy. However,
one of the primary use cases of packet capture is to do black box debugging
of unknown or unexpected behavior. So in some sense they are at odds.</p>
<h3>Istio and mTLS</h3>
<p>One of the primary wins for a service mesh is enhanced security and zero trust
networking. By requiring workloads to communicate via mutual TLS (mTLS),
the underlying Kubernetes network (and the cloud provider VPC it sits on top
of) will only see TLS packets that have been mutually verified.</p>
<p>Due to the use of mTLS, it's crucial that every workload (i.e. pod) in the
mesh has a unique private key and X.509 public certificate. This pair is used
as proof of identity when negotiating mTLS connections. So getting access to
the key for a given workload is crucial to decrypting the traffic.</p>
<h3>Running the Script</h3>
<p>Luckily Envoy has created an incredibly good idea: the <a href="https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol">xDS protocol</a>.
The <code>x</code> stands for "anything here" and the <code>DS</code> for "discovery service". The
whole idea underpinning xDS is that different types of configuration are
relevant (and changing over time) to an Envoy proxy server. The ability
to discover and listen for configuration updates over a range of topics is
incredibly useful for a running server. This protocol is making <a href="https://cloud.google.com/blog/products/networking/traffic-director-supports-proxyless-grpc">traction</a>
directly into gRPC as a way to have all of the benefits of dynamic
configuration without the need for a proxy sidecar.</p>
<p>The xDS protocol includes SDS — secrets discovery service — which
we'll utilize to grab our private key. The <code>istio-sds.go</code> <a href="/code/istio-sds.go">script</a>
facilitates this in several steps.</p>
<h4>Determine Envoy Node ID</h4>
<p>Invoke <code>GET /server_info</code> in the Envoy <a href="https://www.envoyproxy.io/docs/envoy/latest/operations/admin#get--server_info">admin API</a> to determine the
<code>command_line_options.service_node</code> (i.e. the workload or pod identifier
according to Envoy).</p>
<div class=highlight><pre><span></span><code><span class=n>root</span><span class=err>@</span><span class=n>some</span><span class=o>-</span><span class=n>istio</span><span class=o>-</span><span class=n>workload</span><span class=o>-</span><span class=mi>748</span><span class=n>cc777bc</span><span class=o>-</span><span class=n>mvqcf</span><span class=p>:</span><span class=o>/</span><span class=c1># curl http://localhost:15000/server_info</span>
<span class=p>{</span>
<span class=s2>"version"</span><span class=p>:</span> <span class=s2>"73f240a29bece92a8882a36893ccce07b4a54664/1.13.1-dev/Clean/RELEASE/BoringSSL"</span><span class=p>,</span>
<span class=s2>"state"</span><span class=p>:</span> <span class=s2>"LIVE"</span><span class=p>,</span>
<span class=s2>"hot_restart_version"</span><span class=p>:</span> <span class=s2>"11.104"</span><span class=p>,</span>
<span class=s2>"command_line_options"</span><span class=p>:</span> <span class=p>{</span>
<span class=o>...</span>
<span class=s2>"service_node"</span><span class=p>:</span> <span class=s2>"router~10.101.236.171~some-istio-workload-748cc777bc-mvqcf.testing~testing.svc.cluster.local"</span><span class=p>,</span>
<span class=s2>"service_zone"</span><span class=p>:</span> <span class=s2>""</span><span class=p>,</span>
<span class=s2>"mode"</span><span class=p>:</span> <span class=s2>"Serve"</span><span class=p>,</span>
<span class=o>...</span>
<span class=p>},</span>
<span class=s2>"uptime_current_epoch"</span><span class=p>:</span> <span class=s2>"2424451s"</span><span class=p>,</span>
<span class=s2>"uptime_all_epochs"</span><span class=p>:</span> <span class=s2>"2424451s"</span>
<span class=p>}</span>
</code></pre></div>
<h4>Connect to Secrets Discovery Service (SDS)</h4>
<p>Open a gRPC connection to the <code>/etc/istio/proxy/SDS</code> <a href="https://en.wikipedia.org/wiki/Unix_domain_socket">UDS</a> that is
mounted in the <code>istio-proxy</code> sidecar container. As the <code>/SDS</code> in the socket
name indicates, this is the secrets discovery service.</p>
<div class=highlight><pre><span></span><code><span class=nx>ctx</span><span class=p>,</span> <span class=nx>cancel</span> <span class=o>:=</span> <span class=nx>context</span><span class=p>.</span><span class=nx>WithTimeout</span><span class=p>(</span><span class=nx>context</span><span class=p>.</span><span class=nx>Background</span><span class=p>(),</span> <span class=mi>10</span><span class=o>*</span><span class=nx>time</span><span class=p>.</span><span class=nx>Second</span><span class=p>)</span>
<span class=c1>// ...</span>
<span class=nx>conn</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>grpc</span><span class=p>.</span><span class=nx>Dial</span><span class=p>(</span><span class=nx>target</span><span class=p>,</span> <span class=nx>grpc</span><span class=p>.</span><span class=nx>WithInsecure</span><span class=p>(),</span> <span class=nx>grpc</span><span class=p>.</span><span class=nx>WithBlock</span><span class=p>())</span>
<span class=c1>// ...</span>
<span class=nx>c</span> <span class=o>:=</span> <span class=nx>discoveryv2</span><span class=p>.</span><span class=nx>NewSecretDiscoveryServiceClient</span><span class=p>(</span><span class=nx>conn</span><span class=p>)</span>
</code></pre></div>
<h4>Fetch Secret(s) for Current Envoy Node</h4>
<p>Call the <code>FetchSecrets</code> RPC <a href="https://github.com/envoyproxy/envoy/blob/9d466c71ab217317d3e989b261eb496877348a47/api/envoy/service/discovery/v2/sds.proto#L32">method</a> with the <code>node.id</code> <a href="https://github.com/envoyproxy/envoy/blob/9d466c71ab217317d3e989b261eb496877348a47/api/envoy/api/v2/discovery.proto#L35">field</a>
set to the <code>command_line_options.service_node</code> workload identifier</p>
<div class=highlight><pre><span></span><code><span class=nx>request</span> <span class=o>:=</span> <span class=o>&</span><span class=nx>apiv2</span><span class=p>.</span><span class=nx>DiscoveryRequest</span><span class=p>{</span><span class=nx>Node</span><span class=p>:</span> <span class=o>&</span><span class=nx>corev2</span><span class=p>.</span><span class=nx>Node</span><span class=p>{</span><span class=nx>Id</span><span class=p>:</span> <span class=nx>serviceNode</span><span class=p>}}</span>
<span class=nx>response</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>c</span><span class=p>.</span><span class=nx>FetchSecrets</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=nx>request</span><span class=p>,</span> <span class=nx>grpc</span><span class=p>.</span><span class=nx>Header</span><span class=p>(</span><span class=o>&</span><span class=nx>header</span><span class=p>),</span> <span class=nx>grpc</span><span class=p>.</span><span class=nx>Trailer</span><span class=p>(</span><span class=o>&</span><span class=nx>trailer</span><span class=p>))</span>
</code></pre></div>
<h4>Parse the Response</h4>
<p>Ensure the <code>type_url</code> in the response indicates a
<code>envoy.api.v2.auth.Secret</code> and then parse the protobuf <code>Any</code> in the
<code>resources[0]</code> field as a secret:</p>
<div class=highlight><pre><span></span><code><span class=nx>secret</span> <span class=o>:=</span> <span class=o>&</span><span class=nx>authv2</span><span class=p>.</span><span class=nx>Secret</span><span class=p>{}</span>
<span class=nx>err</span> <span class=o>:=</span> <span class=nx>ptypes</span><span class=p>.</span><span class=nx>UnmarshalAny</span><span class=p>(</span><span class=nx>response</span><span class=p>.</span><span class=nx>Resources</span><span class=p>[</span><span class=mi>0</span><span class=p>],</span> <span class=nx>secret</span><span class=p>)</span>
<span class=c1>// ...</span>
<span class=nx>tc</span> <span class=o>:=</span> <span class=nx>secret</span><span class=p>.</span><span class=nx>GetTlsCertificate</span><span class=p>()</span>
<span class=nx>cc</span> <span class=o>:=</span> <span class=nx>tc</span><span class=p>.</span><span class=nx>GetCertificateChain</span><span class=p>()</span>
<span class=c1>// ...</span>
<span class=nx>ccBytes</span> <span class=o>:=</span> <span class=nx>cc</span><span class=p>.</span><span class=nx>GetInlineBytes</span><span class=p>()</span>
<span class=nx>pk</span> <span class=o>:=</span> <span class=nx>tc</span><span class=p>.</span><span class=nx>GetPrivateKey</span><span class=p>()</span>
<span class=c1>// ...</span>
<span class=nx>pkBytes</span> <span class=o>:=</span> <span class=nx>pk</span><span class=p>.</span><span class=nx>GetInlineBytes</span><span class=p>()</span>
</code></pre></div>
<h4>Putting It All Together</h4>
<!-- For posterity
<div class="highlight"><pre><span></span><code>$ go version
go version go1.15.1 linux/amd64
$
$ git --git-dir <span class="si">${</span><span class="nv">GOPATH</span><span class="si">}</span>/src/github.com/envoyproxy/go-control-plane/.git log -1
commit b304c9d56d80fc38b0685bbb42bee68e8270337a <span class="o">(</span>HEAD -> master, origin/master, origin/HEAD<span class="o">)</span>
Author: go-control-plane<span class="o">(</span>CircleCI<span class="o">)</span> <go-control-plane@users.noreply.github.com>
Date: Fri Sep <span class="m">4</span> <span class="m">02</span>:38:16 <span class="m">2020</span> +0000
Mirrored from envoyproxy/envoy @ 9d466c71ab217317d3e989b261eb496877348a47
Signed-off-by: go-control-plane<span class="o">(</span>CircleCI<span class="o">)</span> <go-control-plane@users.noreply.github.com>
</code></pre></div>
-->
<p>Running the script on an Istio / Envoy sidecar will (almost certainly)
require building the binary on a different machine since the container
won't have the toolchain installed<sup id=sf-istio-workload-secrets-3-back><a href=#sf-istio-workload-secrets-3 class=simple-footnote title="If the entire filesystem in the sidecar is read-only, it's impossible to kubectl cp a pre-built binary into the container">3</a></sup>. First build the binary:</p>
<div class=highlight><pre><span></span><code>$ <span class=nv>GOARCH</span><span class=o>=</span>amd64 <span class=nv>GOOS</span><span class=o>=</span>linux go build -o istio-sds-linux-amd64 ./istio-sds.go
</code></pre></div>
<p>then copy it into the container</p>
<div class=highlight><pre><span></span><code><span class=o>$</span> <span class=n>kubectl</span> <span class=n>cp</span> \
<span class=o>></span> <span class=o>--</span><span class=n>namespace</span> <span class=n>testing</span> \
<span class=o>></span> <span class=o>--</span><span class=n>container</span> <span class=n>istio</span><span class=o>-</span><span class=n>proxy</span> \
<span class=o>></span> <span class=o>./</span><span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>-</span><span class=n>linux</span><span class=o>-</span><span class=n>amd64</span> \
<span class=o>></span> <span class=n>some</span><span class=o>-</span><span class=n>istio</span><span class=o>-</span><span class=n>workload</span><span class=o>-</span><span class=mi>748</span><span class=n>cc777bc</span><span class=o>-</span><span class=n>mvqcf</span><span class=p>:</span><span class=o>/</span><span class=n>usr</span><span class=o>/</span><span class=n>local</span><span class=o>/</span><span class=n>bin</span><span class=o>/</span><span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>-</span><span class=n>linux</span><span class=o>-</span><span class=n>amd64</span>
</code></pre></div>
<p>Finally, run the binary in the <code>istio-proxy</code> container to see both the
(public) certificate chain and the private key:</p>
<div class=highlight><pre><span></span><code><span class=o>$</span> <span class=n>kubectl</span> <span class=n>exec</span> \
<span class=o>></span> <span class=o>--</span><span class=n>stdin</span> <span class=o>--</span><span class=n>tty</span> \
<span class=o>></span> <span class=o>--</span><span class=n>namespace</span> <span class=n>testing</span> \
<span class=o>></span> <span class=o>--</span><span class=n>container</span> <span class=n>istio</span><span class=o>-</span><span class=n>proxy</span> \
<span class=o>></span> <span class=n>some</span><span class=o>-</span><span class=n>istio</span><span class=o>-</span><span class=n>workload</span><span class=o>-</span><span class=mi>748</span><span class=n>cc777bc</span><span class=o>-</span><span class=n>mvqcf</span> \
<span class=o>></span> <span class=o>--</span> <span class=o>/</span><span class=n>usr</span><span class=o>/</span><span class=n>local</span><span class=o>/</span><span class=n>bin</span><span class=o>/</span><span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>-</span><span class=n>linux</span><span class=o>-</span><span class=n>amd64</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.710854</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>50</span><span class=p>:</span> <span class=n>GET</span> <span class=n>http</span><span class=p>:</span><span class=o>//</span><span class=n>localhost</span><span class=p>:</span><span class=mi>15000</span><span class=o>/</span><span class=n>server_info</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.713220</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>197</span><span class=p>:</span> <span class=n>Service</span> <span class=n>Node</span><span class=p>:</span> <span class=s2>"router~10.101.236.171~some-istio-workload-748cc777bc-mvqcf.testing~testing.svc.cluster.local"</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.713247</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>200</span><span class=p>:</span> <span class=n>Target</span><span class=p>:</span> <span class=s2>"unix:///etc/istio/proxy/SDS"</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990037</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>211</span><span class=p>:</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990069</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>212</span><span class=p>:</span> <span class=n>DiscoveryResponse</span><span class=o>.</span><span class=n>VersionInfo</span><span class=p>:</span> <span class=s2>"09-04 19:53:34.715"</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990097</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>213</span><span class=p>:</span> <span class=n>DiscoveryResponse</span><span class=o>.</span><span class=n>TypeUrl</span><span class=p>:</span> <span class=s2>"type.googleapis.com/envoy.api.v2.auth.Secret"</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990128</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>176</span><span class=p>:</span> <span class=n>DiscoveryResponse</span><span class=o>.</span><span class=n>Resources</span><span class=p>[</span><span class=mi>0</span><span class=p>]</span><span class=o>.</span><span class=n>GetTlsCertificate</span><span class=p>()</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990145</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>177</span><span class=p>:</span> <span class=n>GetCertificateChain</span><span class=p>():</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990164</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>179</span><span class=p>:</span> <span class=o>-----</span><span class=n>BEGIN</span> <span class=n>CERTIFICATE</span><span class=o>-----</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990179</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>179</span><span class=p>:</span> <span class=o>...</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990421</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>179</span><span class=p>:</span> <span class=o>-----</span><span class=n>END</span> <span class=n>CERTIFICATE</span><span class=o>-----</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990428</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>179</span><span class=p>:</span> <span class=o>-----</span><span class=n>BEGIN</span> <span class=n>CERTIFICATE</span><span class=o>-----</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990435</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>179</span><span class=p>:</span> <span class=o>...</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990634</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>179</span><span class=p>:</span> <span class=o>-----</span><span class=n>END</span> <span class=n>CERTIFICATE</span><span class=o>-----</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990647</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>179</span><span class=p>:</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990661</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>181</span><span class=p>:</span> <span class=n>GetPrivateKey</span><span class=p>():</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990706</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>183</span><span class=p>:</span> <span class=o>-----</span><span class=n>BEGIN</span> <span class=n>RSA</span> <span class=n>PRIVATE</span> <span class=n>KEY</span><span class=o>-----</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.990716</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>183</span><span class=p>:</span> <span class=o>...</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.991035</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>183</span><span class=p>:</span> <span class=o>-----</span><span class=n>END</span> <span class=n>RSA</span> <span class=n>PRIVATE</span> <span class=n>KEY</span><span class=o>-----</span>
<span class=mi>19</span><span class=p>:</span><span class=mi>53</span><span class=p>:</span><span class=mf>34.991049</span> <span class=n>istio</span><span class=o>-</span><span class=n>sds</span><span class=o>.</span><span class=n>go</span><span class=p>:</span><span class=mi>183</span><span class=p>:</span>
</code></pre></div><ol class=simple-footnotes><li id=sf-istio-workload-secrets-1>Not <strong>all</strong>, really <strong>most</strong> <a href=#sf-istio-workload-secrets-1-back class=simple-footnote-back>↩</a></li><li id=sf-istio-workload-secrets-2>The file format used by Wireshark and
<code>tcpdump</code> <a href=#sf-istio-workload-secrets-2-back class=simple-footnote-back>↩</a></li><li id=sf-istio-workload-secrets-3>If the entire filesystem in the sidecar
is read-only, it's <strong>impossible</strong> to <code>kubectl cp</code> a pre-built binary into the
container <a href=#sf-istio-workload-secrets-3-back class=simple-footnote-back>↩</a></li></ol>Preventing PostgreSQL Deadlocks in Go2020-09-01T00:00:00-07:002020-09-01T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-09-01:/2020/09/go-pq-prevent-deadlock.html<p><img alt="All About Locks" src="/images/Lock-Up-The-Forest.jpg"></p>
<p>I've been writing a library for running PostgreSQL migrations in Go. One
of the primary pieces of advice I <a href="https://www.citusdata.com/blog/2018/02/22/seven-tips-for-dealing-with-postgres-locks/">keep</a> coming <a href="https://benchling.engineering/move-fast-and-migrate-things-how-we-automated-migrations-in-postgres-d60aba0fc3d4">across</a> is</p>
<blockquote>
<p>Beware of lock queues, use lock timeouts</p>
</blockquote>
<p>In other words, each migration stage should happen <strong>instantaneously</strong> (or
almost instantaneously). For real-time applications, if a migration runs "for …</p><p><img alt="All About Locks" src="/images/Lock-Up-The-Forest.jpg"></p>
<p>I've been writing a library for running PostgreSQL migrations in Go. One
of the primary pieces of advice I <a href="https://www.citusdata.com/blog/2018/02/22/seven-tips-for-dealing-with-postgres-locks/">keep</a> coming <a href="https://benchling.engineering/move-fast-and-migrate-things-how-we-automated-migrations-in-postgres-d60aba0fc3d4">across</a> is</p>
<blockquote>
<p>Beware of lock queues, use lock timeouts</p>
</blockquote>
<p>In other words, each migration stage should happen <strong>instantaneously</strong> (or
almost instantaneously). For real-time applications, if a migration runs "for a
long time" it can potentially hold a lock that blocks every query in the
application. This post is about the mechanics of setting a <code>lock_timeout</code> in
PostgreSQL via the canonical <code>github.com/lib/pq</code> driver. I'll dive into how it
works, how it contrasts to equivalent connections via <code>psql</code> and we'll go
through four different deadlock scenarios that timeout.</p>
<h3>Contents</h3>
<ul>
<li><a href=#prerequisites>Prerequisites</a></li>
<li><a href=#intentional-contention>Intentional Contention</a></li>
<li><a href=#example-set-up>Example Set Up</a></li>
<li><a href=#failures>Failures</a></li>
<li><code>lock_timeout</code> <a href=#lock-timeout-dsn>in the DSN</a></li>
</ul>
<h3 id=prerequisites>Prerequisites</h3>
<!-- For posterity
<div class="highlight"><pre><span></span><code>$ docker version
Client: Docker Engine - Community
Version: <span class="m">19</span>.03.12
$
$ go version
go version go1.14 darwin/amd64
$
$ git --git-dir <span class="si">${</span><span class="nv">GOPATH</span><span class="si">}</span>/src/github.com/lib/pq/.git log -1 --pretty<span class="o">=</span>%H
ef080b6a8f499b5d60fe9f24a2f8a8beb671566d
$
$ git --git-dir <span class="si">${</span><span class="nv">GOPATH</span><span class="si">}</span>/src/github.com/hashicorp/go-multierror/.git log -1 --pretty<span class="o">=</span>%H
0d28cf682dbe774898e42a3db11b7ce24b36751a
$
$ git --git-dir <span class="si">${</span><span class="nv">GOPATH</span><span class="si">}</span>/src/github.com/hashicorp/errwrap/.git log -1 --pretty<span class="o">=</span>%H
7b00e5db719c64d14dd0caaacbd13e76254d02c0
</code></pre></div>
-->
<p>We'll be on a machine with Docker and Go installed. The Go packages
<code>github.com/lib/pq</code> and <code>github.com/hashicorp/go-multierror</code> should be
installed as well.</p>
<p>In order to run the examples, make sure a local <code>postgres</code> server is
running<sup id=sf-go-pq-prevent-deadlock-1-back><a href=#sf-go-pq-prevent-deadlock-1 class=simple-footnote title="Take note of the connection parameters">1</a></sup>:</p>
<div class=highlight><pre><span></span><code>docker run \
--detach \
--hostname localhost \
--publish 28007:5432 \
--name dev-postgres-prevent-deadlock \
--env POSTGRES_DB=superuser_db \
--env POSTGRES_USER=superuser \
--env POSTGRES_PASSWORD=testpassword_superuser \
postgres:10.6-alpine
</code></pre></div>
<h3 id=intentional-contention>Intentional Contention</h3>
<p>In order to introduce a deadlock, we borrow an example from
<a href="https://www.citusdata.com/blog/2018/02/22/seven-tips-for-dealing-with-postgres-locks/">When Postgres blocks: 7 tips for dealing with locks</a>.
In the first transaction we update "hello" rows followed by "world" rows</p>
<div class=highlight><pre><span></span><code><span class=k>BEGIN</span><span class=p>;</span>
<span class=k>UPDATE</span> <span class=n>might_deadlock</span> <span class=k>SET</span> <span class=n>counter</span> <span class=o>=</span> <span class=n>counter</span> <span class=o>+</span> <span class=mi>1</span> <span class=k>WHERE</span> <span class=k>key</span> <span class=o>=</span> <span class=s1>'hello'</span><span class=p>;</span>
<span class=c1>-- Sleep for 200ms</span>
<span class=k>UPDATE</span> <span class=n>might_deadlock</span> <span class=k>SET</span> <span class=n>counter</span> <span class=o>=</span> <span class=n>counter</span> <span class=o>+</span> <span class=mi>1</span> <span class=k>WHERE</span> <span class=k>key</span> <span class=o>=</span> <span class=s1>'world'</span><span class=p>;</span>
<span class=k>COMMIT</span><span class=p>;</span>
</code></pre></div>
<p>and in the second transaction we update the rows in the opposite order</p>
<div class=highlight><pre><span></span><code><span class=k>BEGIN</span><span class=p>;</span>
<span class=k>UPDATE</span> <span class=n>might_deadlock</span> <span class=k>SET</span> <span class=n>counter</span> <span class=o>=</span> <span class=n>counter</span> <span class=o>+</span> <span class=mi>1</span> <span class=k>WHERE</span> <span class=k>key</span> <span class=o>=</span> <span class=s1>'world'</span><span class=p>;</span>
<span class=c1>-- Sleep for 200ms</span>
<span class=k>UPDATE</span> <span class=n>might_deadlock</span> <span class=k>SET</span> <span class=n>counter</span> <span class=o>=</span> <span class=n>counter</span> <span class=o>+</span> <span class=mi>1</span> <span class=k>WHERE</span> <span class=k>key</span> <span class=o>=</span> <span class=s1>'hello'</span><span class=p>;</span>
<span class=k>COMMIT</span><span class=p>;</span>
</code></pre></div>
<h3 id=example-set-up>Example Set Up</h3>
<p>In order to trigger different failure modes, we allow two different
configurable durations:</p>
<ul>
<li><code>lock_timeout</code> set directly in PostgreSQL (via <code>LOCK_TIMEOUT</code> environment
variable)</li>
<li>Timeout / deadline on a Go <code>context.Context</code> (via <code>CONTEXT_TIMEOUT</code>
environment variable)</li>
</ul>
<p>Additionally, we fix a third duration — the amount of time to sleep
between statements in each transaction — to 200 milliseconds.
By allowing the lock and context timeouts to vary, we can see a failure
manifest in (hopefully) an exhaustive set of scenarios.</p>
<p>Really we are concerned here with checking a few cases:</p>
<ul>
<li>What does <code>postgres</code> do when a lock is held for <code>lock_timeout</code> seconds?</li>
<li>What does <code>postgres</code> do when a lock is held and a Go context is canceled?</li>
<li>What does <code>postgres</code> do when left on its own (i.e. no lock or context
timeout will relinquish the lock)?</li>
</ul>
<p>The <code>pq-prevent-deadlock.go</code> <a href="/code/pq-prevent-deadlock.go">script</a> seeds the <code>might_deadlock</code> table
and then kicks off two simultaneous goroutines to intentionally cause
deadlock. The places in the script relevant to the discussion are the usage of
<code>lock_timeout</code> in the mostly hardcoded connection string (more on this
<a href=#lock-timeout-dsn>later</a>):</p>
<div class=highlight><pre><span></span><code><span class=kd>func</span> <span class=nx>createPool</span><span class=p>(</span><span class=nx>ctx</span> <span class=nx>context</span><span class=p>.</span><span class=nx>Context</span><span class=p>,</span> <span class=nx>cfg</span> <span class=o>*</span><span class=nx>Config</span><span class=p>)</span> <span class=p>(</span><span class=o>*</span><span class=nx>sql</span><span class=p>.</span><span class=nx>DB</span><span class=p>,</span> <span class=kt>error</span><span class=p>)</span> <span class=p>{</span>
<span class=nx>dsnTemplate</span> <span class=o>:=</span> <span class=s>"postgres://superuser:testpassword_superuser@localhost:28007/superuser_db?lock_timeout=%s&sslmode=disable"</span>
<span class=nx>dsn</span> <span class=o>:=</span> <span class=nx>fmt</span><span class=p>.</span><span class=nx>Sprintf</span><span class=p>(</span><span class=nx>dsnTemplate</span><span class=p>,</span> <span class=nx>cfg</span><span class=p>.</span><span class=nx>LockTimeout</span><span class=p>)</span>
<span class=nx>pool</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>sql</span><span class=p>.</span><span class=nx>Open</span><span class=p>(</span><span class=s>"postgres"</span><span class=p>,</span> <span class=nx>dsn</span><span class=p>)</span>
<span class=c1>// ...</span>
<span class=p>}</span>
</code></pre></div>
<p>and the creation of a Go context that sets a deadline based on the context
timeout<sup id=sf-go-pq-prevent-deadlock-2-back><a href=#sf-go-pq-prevent-deadlock-2 class=simple-footnote title="It's crucial that we pass this context in to every database method that has a Context-accepting variant">2</a></sup>:</p>
<div class=highlight><pre><span></span><code><span class=nx>deadline</span> <span class=o>:=</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Now</span><span class=p>().</span><span class=nx>Add</span><span class=p>(</span><span class=nx>cfg</span><span class=p>.</span><span class=nx>ContextTimeout</span><span class=p>)</span>
<span class=nx>ctx</span><span class=p>,</span> <span class=nx>cancel</span> <span class=o>:=</span> <span class=nx>context</span><span class=p>.</span><span class=nx>WithDeadline</span><span class=p>(</span><span class=nx>context</span><span class=p>.</span><span class=nx>Background</span><span class=p>(),</span> <span class=nx>deadline</span><span class=p>)</span>
<span class=k>defer</span> <span class=nx>cancel</span><span class=p>()</span>
</code></pre></div>
<p>The deadlock itself happens in the function kicked off in the goroutines:</p>
<div class=highlight><pre><span></span><code><span class=kd>func</span> <span class=nx>contendReads</span><span class=p>(</span><span class=nx>ctx</span> <span class=nx>context</span><span class=p>.</span><span class=nx>Context</span><span class=p>,</span> <span class=nx>wg</span> <span class=o>*</span><span class=nx>sync</span><span class=p>.</span><span class=nx>WaitGroup</span><span class=p>,</span> <span class=nx>tx</span> <span class=o>*</span><span class=nx>sql</span><span class=p>.</span><span class=nx>Tx</span><span class=p>,</span> <span class=nx>key1</span><span class=p>,</span> <span class=nx>key2</span> <span class=kt>string</span><span class=p>,</span> <span class=nx>cfg</span> <span class=o>*</span><span class=nx>Config</span><span class=p>)</span> <span class=kt>error</span> <span class=p>{</span>
<span class=k>defer</span> <span class=nx>wg</span><span class=p>.</span><span class=nx>Done</span><span class=p>()</span>
<span class=nx>updateRows</span> <span class=o>:=</span> <span class=s>"UPDATE might_deadlock SET counter = counter + 1 WHERE key = $1;"</span>
<span class=nx>_</span><span class=p>,</span> <span class=nx>err</span> <span class=o>:=</span> <span class=nx>tx</span><span class=p>.</span><span class=nx>ExecContext</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=nx>updateRows</span><span class=p>,</span> <span class=nx>key1</span><span class=p>)</span>
<span class=k>if</span> <span class=nx>err</span> <span class=o>!=</span> <span class=kc>nil</span> <span class=p>{</span>
<span class=k>return</span> <span class=nx>err</span>
<span class=p>}</span>
<span class=nx>time</span><span class=p>.</span><span class=nx>Sleep</span><span class=p>(</span><span class=mi>200</span> <span class=o>*</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Millisecond</span><span class=p>)</span>
<span class=nx>_</span><span class=p>,</span> <span class=nx>err</span> <span class=p>=</span> <span class=nx>tx</span><span class=p>.</span><span class=nx>ExecContext</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=nx>updateRows</span><span class=p>,</span> <span class=nx>key2</span><span class=p>)</span>
<span class=k>return</span> <span class=nx>err</span>
<span class=p>}</span>
</code></pre></div>
<h3 id=failures>Failures</h3>
<h4>Via <code>lock_timeout</code></h4>
<p>By setting <code>lock_timeout</code> to 10 milliseconds, much shorter than the 200
millisecond sleep between statements, we can induce <a href="https://www.postgresql.org/docs/10/errcodes-appendix.html">error</a>
<code>55P03: lock_not_available</code> directly from <code>postgres</code>:</p>
<div class=highlight><pre><span></span><code>$ LOCK_TIMEOUT=10ms CONTEXT_TIMEOUT=600ms go run ./pq-prevent-deadlock.go
0.039350 Starting transactions
0.059424 Transactions opened
0.286993 Error(s):
0.287104 - &pq.Error{Severity:"ERROR", Code:"55P03", Message:"canceling statement due to lock timeout", Detail:"", Hint:"", Position:"", InternalPosition:"", InternalQuery:"", Where:"while updating tuple (0,1) in relation \"might_deadlock\"", Schema:"", Table:"", Column:"", DataTypeName:"", Constraint:"", File:"postgres.c", Line:"2989", Routine:"ProcessInterrupts"}
0.287119 - &pq.Error{Severity:"ERROR", Code:"55P03", Message:"canceling statement due to lock timeout", Detail:"", Hint:"", Position:"", InternalPosition:"", InternalQuery:"", Where:"while updating tuple (0,2) in relation \"might_deadlock\"", Schema:"", Table:"", Column:"", DataTypeName:"", Constraint:"", File:"postgres.c", Line:"2989", Routine:"ProcessInterrupts"}
</code></pre></div>
<p>This shows that (A) putting <code>lock_timeout</code> in the connection string used by
Go actually sets a timeout and (B) the database engine does the work of
canceling statements and providing a useful error to the client.</p>
<h4>Force a Deadlock</h4>
<p>By setting <code>lock_timeout</code> <strong>and</strong> the context timeout to 10 seconds, we can
leave <code>postgres</code> on its own to suffer with (and detect) the deadlock.
After less than two seconds the deadlock is detected and error
<code>40P01: deadlock_detected</code> is returned:</p>
<div class=highlight><pre><span></span><code>$ LOCK_TIMEOUT=10s CONTEXT_TIMEOUT=10s go run ./pq-prevent-deadlock.go
0.043090 Starting transactions
0.058350 Transactions opened
1.276383 Error(s):
1.276474 - &pq.Error{Severity:"ERROR", Code:"40P01", Message:"deadlock detected", Detail:"Process 2385 waits for ShareLock on transaction 624; blocked by process 2384.\nProcess 2384 waits for ShareLock on transaction 625; blocked by process 2385.", Hint:"See server log for query details.", Position:"", InternalPosition:"", InternalQuery:"", Where:"while updating tuple (0,1) in relation \"might_deadlock\"", Schema:"", Table:"", Column:"", DataTypeName:"", Constraint:"", File:"deadlock.c", Line:"1140", Routine:"DeadLockReport"}
</code></pre></div>
<h4>Go <code>context</code> Cancelation In Between Queries in a Transaction</h4>
<p>By setting the context timeout to 100 milliseconds (half the length of the
sleep between statements), the transaction will be canceled <strong>during</strong> the
sleep which means the next statement will not even attempt to communicate
with <code>postgres</code>:</p>
<div class=highlight><pre><span></span><code>$ LOCK_TIMEOUT=10s CONTEXT_TIMEOUT=100ms go run ./pq-prevent-deadlock.go
0.049146 Starting transactions
0.060474 Transactions opened
0.268488 Error(s):
0.268542 - context.deadlineExceededError{}
0.268547 - context.deadlineExceededError{}
</code></pre></div>
<h4>Cancel "Stuck" Deadlock via Go context Cancelation</h4>
<p>Setting the context timeout to 600 milliseconds is long enough that the sleep
between statements completes but not so long that <code>postgres</code> detects the
deadlock. In this case a <code>57014: query_canceled</code> is returned:</p>
<div class=highlight><pre><span></span><code>$ LOCK_TIMEOUT=10s CONTEXT_TIMEOUT=600ms go run ./pq-prevent-deadlock.go
0.037892 Starting transactions
0.048328 Transactions opened
0.610551 Error(s):
0.610640 - &pq.Error{Severity:"ERROR", Code:"57014", Message:"canceling statement due to user request", Detail:"", Hint:"", Position:"", InternalPosition:"", InternalQuery:"", Where:"while updating tuple (0,1) in relation \"might_deadlock\"", Schema:"", Table:"", Column:"", DataTypeName:"", Constraint:"", File:"postgres.c", Line:"3026", Routine:"ProcessInterrupts"}
0.610663 - &pq.Error{Severity:"ERROR", Code:"57014", Message:"canceling statement due to user request", Detail:"", Hint:"", Position:"", InternalPosition:"", InternalQuery:"", Where:"while updating tuple (0,2) in relation \"might_deadlock\"", Schema:"", Table:"", Column:"", DataTypeName:"", Constraint:"", File:"postgres.c", Line:"3026", Routine:"ProcessInterrupts"}
</code></pre></div>
<p>This is somewhat of a pleasant surprise because the in-flight statement:</p>
<div class=highlight><pre><span></span><code><span class=nx>time</span><span class=p>.</span><span class=nx>Sleep</span><span class=p>(</span><span class=mi>200</span> <span class=o>*</span> <span class=nx>time</span><span class=p>.</span><span class=nx>Millisecond</span><span class=p>)</span>
<span class=nx>_</span><span class=p>,</span> <span class=nx>err</span> <span class=p>=</span> <span class=nx>tx</span><span class=p>.</span><span class=nx>ExecContext</span><span class=p>(</span><span class=nx>ctx</span><span class=p>,</span> <span class=nx>updateRows</span><span class=p>,</span> <span class=nx>key2</span><span class=p>)</span>
</code></pre></div>
<p>might very well be expected to block indefinitely. Instead, an event loop
in <code>github.com/lib/pq</code> detects the context cancelation and manages to
communicate the canceled query to <code>postgres</code> as well.</p>
<h3 id=lock-timeout-dsn><code>lock_timeout</code> in the DSN</h3>
<p>Though <code>lock_timeout</code> is directly supported in the connection string in
<code>github.com/lib/pq</code>, it's <a href="https://www.postgresql.org/docs/10/libpq-connect.html#LIBPQ-PARAMKEYWORDS">explicitly</a> <strong>not</strong> supported in
<code>psql</code> / <code>libpq</code>:</p>
<div class=highlight><pre><span></span><code>$ psql "postgres://superuser:testpassword_superuser@localhost:28007/superuser_db?lock_timeout=10ms&sslmode=disable"
psql: error: could not connect to server: invalid URI query parameter: "lock_timeout"
</code></pre></div>
<p>Instead <code>github.com/lib/pq</code> parses all query parameters when <a href="https://github.com/lib/pq/blob/v1.8.0/connector.go#L67-L69">reading a DSN</a>
and then passes all non-driver settings through as key-value pairs when
<a href="https://github.com/lib/pq/blob/v1.8.0/conn.go#L1093-L1105">forming a startup packet</a>. There are 13<sup id=sf-go-pq-prevent-deadlock-3-back><a href=#sf-go-pq-prevent-deadlock-3 class=simple-footnote title="Though 13 are supported by github.com/lib/pq, there are 29 postgres parameter keywords">3</a></sup>
designated driver settings <a href="https://github.com/lib/pq/blob/v1.8.0/conn.go#L1058-L1084">supported by</a> <code>github.com/lib/pq</code>: <code>host</code>,
<code>port</code>, ..., etc.</p>
<h4>What's the <code>psql</code> Equivalent?</h4>
<p>From the <a href="https://www.postgresql.org/docs/10/protocol-flow.html#id-1.10.5.7.3">Start-up</a> section of the documentation for
"Frontend/Backend Protocol > Message Flow", we see</p>
<blockquote>
<p>To begin a session, a frontend opens a connection to the server and sends a
startup message ... (Optionally, the startup message can include additional
settings for run-time parameters.)</p>
</blockquote>
<p>Using <code>PGOPTIONS="-c {key}={value}"</code> with <code>psql</code> enables <a href="https://www.postgresql.org/docs/10/app-postgres.html#id-1.9.5.13.6.3">setting</a>
named run-time parameters<sup id=sf-go-pq-prevent-deadlock-4-back><a href=#sf-go-pq-prevent-deadlock-4 class=simple-footnote title="It's also worth noting that github.com/lib/pq is PGOPTIONS-aware">4</a></sup>:</p>
<div class=highlight><pre><span></span><code>$ PGOPTIONS="-c lock_timeout=10ms" psql "postgres://superuser:testpassword_superuser@localhost:28007/superuser_db?connect_timeout=5&sslmode=disable"
...
superuser_db=# SHOW lock_timeout;
lock_timeout
--------------
10ms
(1 row)
superuser_db=# \q
</code></pre></div><ol class=simple-footnotes><li id=sf-go-pq-prevent-deadlock-1>Take note of the connection parameters <a href=#sf-go-pq-prevent-deadlock-1-back class=simple-footnote-back>↩</a></li><li id=sf-go-pq-prevent-deadlock-2>It's crucial that we pass this context in to every database
method that has a <code>Context</code>-accepting variant <a href=#sf-go-pq-prevent-deadlock-2-back class=simple-footnote-back>↩</a></li><li id=sf-go-pq-prevent-deadlock-3>Though 13 are supported by
<code>github.com/lib/pq</code>, there are 29 <code>postgres</code> <a href="https://www.postgresql.org/docs/10/libpq-connect.html#LIBPQ-PARAMKEYWORDS">parameter keywords</a> <a href=#sf-go-pq-prevent-deadlock-3-back class=simple-footnote-back>↩</a></li><li id=sf-go-pq-prevent-deadlock-4>It's also worth noting that <code>github.com/lib/pq</code>
is <code>PGOPTIONS</code>-<a href="https://github.com/lib/pq/blob/v1.8.0/conn.go#L1945-L1946">aware</a> <a href=#sf-go-pq-prevent-deadlock-4-back class=simple-footnote-back>↩</a></li></ol>How Do Slices Gain Capacity in Go?2020-07-29T00:00:00-07:002020-07-29T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-07-29:/2020/07/go-slices-gain-capacity.html<h3>Looking Inside a Slice</h3>
<p>The first thing to realize is that a <code>slice</code> in Go is really just a struct
that wraps "header" information about (1) a pointer to the "real" underlying
data, (2) the length and (3) the capacity without directly exposing those
fields. We can use a <code>struct …</code></p><h3>Looking Inside a Slice</h3>
<p>The first thing to realize is that a <code>slice</code> in Go is really just a struct
that wraps "header" information about (1) a pointer to the "real" underlying
data, (2) the length and (3) the capacity without directly exposing those
fields. We can use a <code>struct</code> like:</p>
<div class="highlight"><pre><span></span><code><span class="kd">type</span> <span class="nx">IntSlice</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="nx">Start</span> <span class="o">*</span><span class="kt">int</span> <span class="c1">// (1)</span>
<span class="nx">Length</span> <span class="kt">int</span> <span class="c1">// (2)</span>
<span class="nx">Capacity</span> <span class="kt">int</span> <span class="c1">// (3)</span>
<span class="p">}</span>
</code></pre></div>
<p>to unpack the fields in use. Putting this in a script:</p>
<div class="highlight"><pre><span></span><code><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">"fmt"</span>
<span class="s">"unsafe"</span>
<span class="p">)</span>
<span class="kd">type</span> <span class="nx">IntSlice</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="nx">Start</span> <span class="o">*</span><span class="kt">int</span> <span class="c1">// (1)</span>
<span class="nx">Length</span> <span class="kt">int</span> <span class="c1">// (2)</span>
<span class="nx">Capacity</span> <span class="kt">int</span> <span class="c1">// (3)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nx">FromSlice</span><span class="p">(</span><span class="nx">ps</span> <span class="o">*</span><span class="p">[]</span><span class="kt">int</span><span class="p">)</span> <span class="o">*</span><span class="nx">IntSlice</span> <span class="p">{</span>
<span class="nx">p</span> <span class="o">:=</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nx">Pointer</span><span class="p">(</span><span class="nx">ps</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="o">*</span><span class="nx">IntSlice</span><span class="p">)(</span><span class="nx">p</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nx">Display</span><span class="p">(</span><span class="nx">ps</span> <span class="o">*</span><span class="p">[]</span><span class="kt">int</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">is</span> <span class="o">:=</span> <span class="nx">FromSlice</span><span class="p">(</span><span class="nx">ps</span><span class="p">)</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">"%#v\n"</span><span class="p">,</span> <span class="nx">is</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">s</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="nx">Display</span><span class="p">(</span><span class="o">&</span><span class="nx">s</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>we can verify that <code>IntSlice</code> accurately describes an <code>[]int</code> slice:</p>
<div class="highlight"><pre><span></span><code>$ go run docs/go-slices-gain-capacity/unsafe/main.go
<span class="p">&</span>main.IntSlice<span class="o">{</span>Start:<span class="o">(</span>*int<span class="o">)(</span>0xc0000b4020<span class="o">)</span>, Length:0, Capacity:3<span class="o">}</span>
</code></pre></div>
<p>Note that conversion from <code>[]int</code> to <code>IntSlice</code> isn't straightforward. It
requires use of the <code>unsafe</code> Go package to interact with raw pointers:</p>
<div class="highlight"><pre><span></span><code><span class="kd">func</span> <span class="nx">FromSlice</span><span class="p">(</span><span class="nx">ps</span> <span class="o">*</span><span class="p">[]</span><span class="kt">int</span><span class="p">)</span> <span class="o">*</span><span class="nx">IntSlice</span> <span class="p">{</span>
<span class="nx">p</span> <span class="o">:=</span> <span class="nx">unsafe</span><span class="p">.</span><span class="nx">Pointer</span><span class="p">(</span><span class="nx">ps</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="o">*</span><span class="nx">IntSlice</span><span class="p">)(</span><span class="nx">p</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<h3>Printing Useful Information</h3>
<p>In order to understand how the slice changes when it needs to gain capacity,
it's useful for us to see if the address of the <code>[]int</code> slice itself changes
as well as to see if the underlying <code>Start</code> address changes. We can update
<code>Display()</code> to incorporate this information in a useful way:</p>
<div class="highlight"><pre><span></span><code><span class="kd">func</span> <span class="nx">Display</span><span class="p">(</span><span class="nx">ps</span> <span class="o">*</span><span class="p">[]</span><span class="kt">int</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">is</span> <span class="o">:=</span> <span class="nx">FromSlice</span><span class="p">(</span><span class="nx">ps</span><span class="p">)</span>
<span class="nx">s</span> <span class="o">:=</span> <span class="o">*</span><span class="nx">ps</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span>
<span class="s">"s=%v | &s=%p, start=%p, len=%d, cap=%d\n"</span><span class="p">,</span>
<span class="nx">s</span><span class="p">,</span> <span class="nx">ps</span><span class="p">,</span> <span class="nx">is</span><span class="p">.</span><span class="nx">Start</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="nx">s</span><span class="p">),</span> <span class="nb">cap</span><span class="p">(</span><span class="nx">s</span><span class="p">),</span>
<span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>which yields:</p>
<div class="highlight"><pre><span></span><code>$ go run docs/go-slices-gain-capacity/useful/main.go
<span class="nv">s</span><span class="o">=[]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc0000b4020, <span class="nv">len</span><span class="o">=</span><span class="m">0</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">3</span>
</code></pre></div>
<h3><code>append()</code> Until Capacity Runs Out</h3>
<p>Now that we can actually "observe" the underlying data in a slice, we can
continue to use <code>append()</code> to grow the slice:</p>
<div class="highlight"><pre><span></span><code><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">s</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="nx">Display</span><span class="p">(</span><span class="o">&</span><span class="nx">s</span><span class="p">)</span>
<span class="k">for</span> <span class="nx">i</span> <span class="o">:=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="p"><</span> <span class="mi">8</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span> <span class="p">{</span>
<span class="nx">s</span> <span class="p">=</span> <span class="nb">append</span><span class="p">(</span><span class="nx">s</span><span class="p">,</span> <span class="nx">i</span><span class="o">*</span><span class="nx">i</span><span class="p">)</span>
<span class="nx">Display</span><span class="p">(</span><span class="o">&</span><span class="nx">s</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>We see that when the capacity changes (from 3 to 6 to 12) the pointer to the
underyling data changes as well (from <code>0xc0000b4020</code> to <code>0xc0000aa060</code> to
<code>0xc00008c060</code>):</p>
<div class="highlight"><pre><span></span><code>$ go run docs/go-slices-gain-capacity/exceed/main.go
<span class="nv">s</span><span class="o">=[]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc0000b4020, <span class="nv">len</span><span class="o">=</span><span class="m">0</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">3</span>
<span class="nv">s</span><span class="o">=[</span><span class="m">1</span><span class="o">]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc0000b4020, <span class="nv">len</span><span class="o">=</span><span class="m">1</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">3</span>
<span class="nv">s</span><span class="o">=[</span><span class="m">1</span> <span class="m">4</span><span class="o">]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc0000b4020, <span class="nv">len</span><span class="o">=</span><span class="m">2</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">3</span>
<span class="nv">s</span><span class="o">=[</span><span class="m">1</span> <span class="m">4</span> <span class="m">9</span><span class="o">]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc0000b4020, <span class="nv">len</span><span class="o">=</span><span class="m">3</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">3</span>
<span class="nv">s</span><span class="o">=[</span><span class="m">1</span> <span class="m">4</span> <span class="m">9</span> <span class="m">16</span><span class="o">]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc0000aa060, <span class="nv">len</span><span class="o">=</span><span class="m">4</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">6</span>
<span class="nv">s</span><span class="o">=[</span><span class="m">1</span> <span class="m">4</span> <span class="m">9</span> <span class="m">16</span> <span class="m">25</span><span class="o">]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc0000aa060, <span class="nv">len</span><span class="o">=</span><span class="m">5</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">6</span>
<span class="nv">s</span><span class="o">=[</span><span class="m">1</span> <span class="m">4</span> <span class="m">9</span> <span class="m">16</span> <span class="m">25</span> <span class="m">36</span><span class="o">]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc0000aa060, <span class="nv">len</span><span class="o">=</span><span class="m">6</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">6</span>
<span class="nv">s</span><span class="o">=[</span><span class="m">1</span> <span class="m">4</span> <span class="m">9</span> <span class="m">16</span> <span class="m">25</span> <span class="m">36</span> <span class="m">49</span><span class="o">]</span> <span class="p">|</span> <span class="p">&</span><span class="nv">s</span><span class="o">=</span>0xc0000a6040, <span class="nv">start</span><span class="o">=</span>0xc00008c060, <span class="nv">len</span><span class="o">=</span><span class="m">7</span>, <span class="nv">cap</span><span class="o">=</span><span class="m">12</span>
</code></pre></div>
<p>As a nice bonus we also see that the address of our slice <code>s</code> doesn't change
even though we overwrite it nine times.</p>A Day in the Life of a (Secure) Request2020-07-27T00:00:00-07:002020-07-27T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-07-27:/2020/07/life-of-request.html<p>I recently<sup id=sf-life-of-request-1-back><a href=#sf-life-of-request-1 class=simple-footnote title="It was recent when I wrote this on July 27, 2020.">1</a></sup> had the
privilege of co-authoring a blog post on the Blend <a href="https://full-stack.blend.com/">engineering blog</a> with
my esteemed colleague <a href="https://github.com/hapoore">Austin Poore</a>. Our engineering organization is
growing like crazy right now and it's a lot of fun so if any of this post is
interesting to you, check out our …</p><p>I recently<sup id=sf-life-of-request-1-back><a href=#sf-life-of-request-1 class=simple-footnote title="It was recent when I wrote this on July 27, 2020.">1</a></sup> had the
privilege of co-authoring a blog post on the Blend <a href="https://full-stack.blend.com/">engineering blog</a> with
my esteemed colleague <a href="https://github.com/hapoore">Austin Poore</a>. Our engineering organization is
growing like crazy right now and it's a lot of fun so if any of this post is
interesting to you, check out our careers page. I copied this content
over mostly as-is from the <a href="https://full-stack.blend.com/a-day-in-the-life-of-a-secure-request.html">original post</a> but wanted to preserve it here
as well.</p>
<h3>Contents</h3>
<ul>
<li><a href=#introduction>Introduction</a></li>
<li><a href=#example-express-server>Example Express Server</a></li>
<li><a href=#tls-proxy>TLS Proxy</a></li>
<li><a href=#load-balancers-and-proxy-protocol>Load Balancers and PROXY Protocol</a></li>
<li><a href=#putting-it-all-together>Putting it all Together</a></li>
</ul>
<p><img alt="All hops" src="/images/life-of-a-secure-request.jpg"></p>
<h3 id=introduction>Introduction</h3>
<p>In this post, we will walk through the infrastructure components we use at
Blend to secure incoming requests—a day in the life of a request, if you
will. There are a variety of commonly-used mechanisms to secure cloud computing
environments, which often involve load balancers and special-purpose proxy
servers. As a result, requests from a client to an application server
typically make a number of intermediate network hops en route to their final
destination.</p>
<p>We'll provide a number of examples that you can run yourself as you follow
along. Then, armed with our new understanding, we'll put it all together at the
end and explain how, despite the intermediate hops, we can still accurately
determine a client's IP address by the time a request makes it to our
application servers.</p>
<h3 id=example-express-server>Example Express Server</h3>
<p>We'll start with the innermost server (our application server) and work our way
outwards. We build many of our backend services at Blend using Node.js and
Express, so that's what we'll use for our sample application server today.
Though we primarily use TypeScript when writing Node.js applications, we'll
use vanilla JavaScript for this example to make it accessible to a larger
audience.</p>
<p>If you'd like to follow along, now is the time to fire up your favorite text
editor. Here we go!
We'll first create a web server<sup id=sf-life-of-request-2-back><a href=#sf-life-of-request-2 class=simple-footnote title="See source for server.js.">2</a></sup>
using Node.js and Express:</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>express</span> <span class=o>=</span> <span class=nx>require</span><span class=p>(</span><span class=s1>'express'</span><span class=p>);</span>
<span class=kd>const</span> <span class=nx>app</span> <span class=o>=</span> <span class=nx>express</span><span class=p>();</span>
<span class=kd>const</span> <span class=nx>port</span> <span class=o>=</span> <span class=mf>3000</span><span class=p>;</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>get</span><span class=p>(</span><span class=s1>'/'</span><span class=p>,</span> <span class=p>(</span><span class=nx>req</span><span class=p>,</span> <span class=nx>res</span><span class=p>)</span> <span class=p>=></span> <span class=p>{</span>
<span class=nx>msg</span> <span class=o>=</span> <span class=p>[</span>
<span class=sb>`req.ip: </span><span class=si>${</span><span class=nx>JSON</span><span class=p>.</span><span class=nx>stringify</span><span class=p>(</span><span class=nx>req</span><span class=p>.</span><span class=nx>ip</span><span class=p>)</span><span class=si>}</span><span class=sb>`</span><span class=p>,</span>
<span class=sb>`req.xff: </span><span class=si>${</span><span class=nx>JSON</span><span class=p>.</span><span class=nx>stringify</span><span class=p>(</span><span class=nx>req</span><span class=p>.</span><span class=nx>get</span><span class=p>(</span><span class=s1>'x-forwarded-for'</span><span class=p>))</span><span class=si>}</span><span class=sb>`</span><span class=p>,</span>
<span class=s1>''</span><span class=p>,</span>
<span class=p>].</span><span class=nx>join</span><span class=p>(</span><span class=s1>'\n'</span><span class=p>)</span>
<span class=nx>res</span><span class=p>.</span><span class=nx>send</span><span class=p>(</span><span class=nx>msg</span><span class=p>)</span>
<span class=p>});</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>listen</span><span class=p>(</span><span class=nx>port</span><span class=p>,</span> <span class=p>()</span> <span class=p>=></span> <span class=nx>console</span><span class=p>.</span><span class=nx>log</span><span class=p>(</span><span class=sb>`Example app listening on port </span><span class=si>${</span><span class=nx>port</span><span class=si>}</span><span class=sb>!`</span><span class=p>));</span>
</code></pre></div>
<p>In one terminal window, run this server<sup id=sf-life-of-request-3-back><a href=#sf-life-of-request-3 class=simple-footnote title="Running server.js will require having node and npm installed, in a directory with a package.json file. For our example we are using node@12.14.1, npm@6.13.4 and installing Express with npm install express@4.17.1 --save-exact.">3</a></sup>:</p>
<div class=highlight><pre><span></span><code>$ node ./server.js
Example app listening on port 3000!
</code></pre></div>
<p>In another terminal window, send a request to the server:</p>
<div class=highlight><pre><span></span><code>$ curl http://localhost:3000
req.ip: "::1"
req.xff: undefined
</code></pre></div>
<p>This server exposes one route, which returns the IP address and the value of
the <code>X-Forwarded-For</code> (XFF) <a href="https://en.wikipedia.org/wiki/X-Forwarded-For">HTTP header</a> on the request object (more on
this later). By default, Express populates the <code>req.ip</code> field with the address
on the other end of the TCP socket making the connection to the server. As
expected, when we send a request from our machine to the server (also running
on our machine), we see that the requestor IP address is the familiar loopback
IP for <code>localhost</code> (<code>::1</code> for IPv6, or <code>127.0.0.1</code> for IPv4).</p>
<h3 id=tls-proxy>TLS Proxy</h3>
<p><img alt="TLS Proxy" src="/images/life-of-a-secure-request-third-hop.jpg"></p>
<p>In order to secure traffic, web servers use TLS (i.e. the protocol underlying
<code>https://</code> connections). Negotiating a TLS session is quite <a href="https://tls13.ulfheim.net/">complex</a>; we
won't go into the full details here. In order to run and test a TLS server
locally (as part of this blog post), we'll use a private key / public
certificate pair and a certificate authority (CA) that can be added to a root
of trust<sup id=sf-life-of-request-4-back><a href=#sf-life-of-request-4 class=simple-footnote title="See Generated Certificates for localhost.">4</a></sup>.</p>
<p>In a microservices architecture, having many services worrying about
<strong>how</strong> to handle TLS and all that goes into it (e.g. when to rotate
certificates) doesn't scale well. Instead, a dedicated TLS proxy (commonly
referred to as a reverse proxy or ingress proxy) can be used to secure incoming
connections and shuffle traffic to and from the underlying microservices. In
the sidecar model enabled by Kubernetes, such a TLS proxy can be a very
lightweight Docker container running in the same pod as an application
container and communicating with the application directly over <code>localhost</code>
while communicating with the outside world securely over TLS.</p>
<p>In order to approximate such a TLS proxy as part of our example, we'll
use the handy <code>caddy</code> <a href="https://caddyserver.com/">server</a><sup id=sf-life-of-request-5-back><a href=#sf-life-of-request-5 class=simple-footnote title="We install version 1 of caddy with http.proxyprotocol enabled. The feature is not yet supported in version 2 of caddy.">5</a></sup>. We'll use this to run a TLS proxy on port 3443
fronting the webserver on port 3000, with the following <code>Caddyfile</code><sup id=sf-life-of-request-6-back><a href=#sf-life-of-request-6 class=simple-footnote title="See source for tls.Caddyfile.">6</a></sup></p>
<div class=highlight><pre><span></span><code>:3443
proxy / localhost:3000
tls ./localhost-cert.pem ./localhost-key.pem
log stdout
</code></pre></div>
<p>We can run this proxy server and communicate with it over TLS<sup id=sf-life-of-request-7-back><a href=#sf-life-of-request-7 class=simple-footnote title="See Why --cacert Flag.">7</a></sup> with <code>curl</code> to verify that it proxies
traffic to port 3000:</p>
<div class=highlight><pre><span></span><code>$ caddy -conf ./tls.Caddyfile &
Activating privacy features... done.
Serving HTTPS on port 3443
https://:3443
...
$ curl --cacert ./rootCA-cert.pem https://localhost:3443
req.ip: "::1"
req.xff: "::1"
</code></pre></div>
<p>When a TLS sidecar container forwards an HTTP request to an application
container, it attaches its view of the client IP address using the
XFF HTTP header. This header is widely used, and can already contain a list of
values. (For example, if a request was forwarded multiple times before entering
our system, external proxies may have also written to the header.) The TLS
proxy either sets the XFF header or adds an entry to the end of the XFF list if
the header is already present:</p>
<div class=highlight><pre><span></span><code>$ curl \
> --cacert ./rootCA-cert.pem \
> --header 'X-Forwarded-For: 127.0.0.2' \
> https://localhost:3443
req.ip: "::1"
req.xff: "127.0.0.2, ::1"
</code></pre></div>
<h3 id=load-balancers-and-proxy-protocol>Load Balancers and PROXY Protocol</h3>
<p><img alt="Into ELB" src="/images/life-of-a-secure-request-first-hop.jpg"></p>
<p>To secure cloud computing environments, it's common to isolate environments
(test, beta, production, etc.) into virtual private networks. This way,
traffic <strong>between</strong> internal services is secured within the private network
and traffic <strong>into</strong> the network requires special access. Traffic is typically
allowed <strong>into</strong> the network with a load balancer, which means that
a request passes through a load balancer before making it to an application
server.</p>
<p>There are two common types of load balancer: <a href="https://www.nginx.com/resources/glossary/layer-4-load-balancing/">L4 and L7</a>. Layer 4 (in the
<a href="https://en.wikipedia.org/wiki/OSI_model">OSI model</a>) represents the transport layer (e.g. TCP), whereas layer 7
represents the application layer (e.g. HTTP). HTTP load balancing can be
<strong>very</strong> helpful since it can do load balancing based on path and header
information and inject headers when passing traffic along. However, TLS traffic
can't be decrypted unless a layer 7 load balancer is terminating the
connection. As a result, layer 4 load balancers are still very common because
they allow application code to handle TLS directly.</p>
<p><img alt="OSI Model" src="/images/osi-model.svg"></p>
<p>At Blend, we use layer 4 load balancers so we can use a highly configurable
TLS reverse proxy. Unfortunately, since a layer 4 load balancer cannot decrypt
the TLS traffic, it can't add information about the originating client when
forwarding requests along to an application server. However, the client's IP
address can be a crucial piece of information when validating an incoming
request, so the <a href="http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt">PROXY protocol spec</a> defines a way to pass this along.
Rather than modifying the encrypted bytes, a header is prepended to the TCP
bytesteam<sup id=sf-life-of-request-8-back><a href=#sf-life-of-request-8 class=simple-footnote title="See Observing PROXY Protocol.">8</a></sup>.
For <a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html">example</a> with an IPv4 connection:</p>
<div class=highlight><pre><span></span><code>PROXY TCP4 198.51.100.22 203.0.113.7 35646 80\r\n
</code></pre></div>
<p>To utilize this information, we can modify our <code>Caddyfile</code> to enable the
<a href="https://caddyserver.com/v1/docs/http.proxyprotocol"><code>http.proxyprotocol</code> filter</a><sup id=sf-life-of-request-9-back><a href=#sf-life-of-request-9 class=simple-footnote title="See source for proxy-protocol.Caddyfile.">9</a></sup>. After doing this, we can use <code>curl</code> to pass
along a PROXY protocol prefix and verify the Caddy server handles it:</p>
<div class=highlight><pre><span></span><code>$ caddy -conf ./proxy-protocol.Caddyfile &
...
$ curl --haproxy-protocol \
> --cacert ./rootCA-cert.pem https://localhost:3443
req.ip: "::1"
req.xff: "::1"
</code></pre></div>
<p><img alt="From ELB" src="/images/life-of-a-secure-request-second-hop.jpg"></p>
<p>However, since all IP addresses (including those in the PROXY protocol prefix)
are <code>localhost</code>, the example is somewhat unsatisfying. Instead, we'll use
another of our favorite tools at Blend—the Go programming language—
to simulate the example above involving <code>198.51.100.22</code>. We can use a raw TCP
socket, manually send the PROXY protocol prefix and then wrap the socket in a
TLS connection<sup id=sf-life-of-request-10-back><a href=#sf-life-of-request-10 class=simple-footnote title="See source for wrapped-request.go.">10</a></sup>:</p>
<div class=highlight><pre><span></span><code>$ go run ./wrapped-request.go
req.ip: "::1"
req.xff: "127.0.0.4, 127.0.0.3, 127.0.0.2, 198.51.100.22"
</code></pre></div>
<h3 id=putting-it-all-together>Putting it all Together</h3>
<p>At this point, we've developed an understanding of all of the individual
pieces. In this section, we will put them all together from end-to-end and
test our complete understanding by working through the full process by which
we can preserve a requestor's IP address through multiple intermediate hops.</p>
<p>More precisely, we'd like to be able to determine the IP address used to
connect directly to our system. If, for example, the caller is using an
egress proxy that forwards requests from a group of machines, the address of
that egress proxy is the only address that we are able to reliably verify,
because anything that happened in the life of the request before the direct
connection to Blend could be spoofed. To put it another way: we can only fully
trust our own infrastructure.</p>
<p>As mentioned above, most of our backend services at Blend run with sidecar
containers<sup id=sf-life-of-request-11-back><a href=#sf-life-of-request-11 class=simple-footnote title="Sidecars are separate containers that belong to the same Kubernetes pod.">11</a></sup> which handle TLS and forward traffic to our
application server containers. This means that our application code does not
need to be aware of TLS—it communicates with the TLS proxy in cleartext
over <code>localhost</code>. Since the proxy connects to the application server in this
way, our Express server running with default settings would populate
<code>req.ip</code> using the address from the TCP socket (which would be <code>localhost</code>, as
in our initial example).</p>
<p>Luckily, Express is <a href="https://expressjs.com/en/guide/behind-proxies.html">commonly used</a> with proxies, so there is a helpful
setting we can use to instruct our server to use the XFF information on the
request to populate <code>req.ip</code>. In particular, we know that there is a single
trusted proxy in the request's path that is appending an entry to XFF: our TLS
sidecar. Thus, we can set <code>app.set('trust proxy', 1)</code> on our Express
application, which tells our server that <code>req.ip</code> should be set based on the
last entry in XFF. Running our server<sup id=sf-life-of-request-12-back><a href=#sf-life-of-request-12 class=simple-footnote title="See source for server-trust.js.">12</a></sup> with "trust proxy", we see <code>req.ip</code> derived from XFF
rather than the TCP socket:</p>
<div class=highlight><pre><span></span><code>$ node ./server-trust.js
Example app listening on port 3000!
...
$ go run ./wrapped-request.go
req.ip: "198.51.100.22"
req.xff: "127.0.0.4, 127.0.0.3, 127.0.0.2, 198.51.100.22"
</code></pre></div>
<p>So, a typical request<sup id=sf-life-of-request-13-back><a href=#sf-life-of-request-13 class=simple-footnote title="See Warning about trust proxy.">13</a></sup> will proceed from client
to application server as follows:</p>
<ol>
<li>Request originates at the client (e.g. IP address <code>198.51.100.22</code>) and gets
routed to the AWS load balancer.</li>
<li>The AWS load balancer reads the client IP address from the TCP socket,
and uses the PROXY protocol to attach that information to the beginning of
the TCP bytestream that it forwards to the TLS proxy sidecar container.</li>
<li>The TLS sidecar container reads the first set of bytes from the TCP stream,
sees that they say "PROXY", and strips those bytes (plus the IP address
information) off of the TCP stream. It negotiates the TLS handshake with
the client. It also attaches <code>X-Forwarded-For: 198.51.100.22</code> to each
proxied HTTP request.</li>
<li>The application server, which is an Express server running with
<code>('trust proxy', 1)</code>, automatically pulls the last entry from <code>X-Forwarded-For</code> and
sets <code>req.ip</code> to <code>198.51.100.22</code>.</li>
</ol>
<hr>
<h3>Extended Footnotes</h3>
<h4 id=netcat-proxy-protocol>Observing PROXY Protocol</h4>
<p>To concretely understand how PROXY protocol works, we can use
<a href="https://en.wikipedia.org/wiki/Netcat">netcat</a> (<code>nc</code>) to print out the raw TCP stream sent in an HTTP
request. Compare a regular HTTP GET</p>
<div class=highlight><pre><span></span><code>$ (echo WITHOUT | nc -l 9876 &) && \
> curl http://localhost:9876
GET / HTTP/1.1
Host: localhost:9876
User-Agent: curl/7.64.1
Accept: */*
WITHOUT
</code></pre></div>
<p>to an HTTP GET with the PROXY protocol prefix:</p>
<div class=highlight><pre><span></span><code>$ (echo WITH | nc -l 9876 &) && \
> curl --haproxy-protocol http://localhost:9876
PROXY TCP4 127.0.0.1 127.0.0.1 53577 9876
GET / HTTP/1.1
Host: localhost:9876
User-Agent: curl/7.64.1
Accept: */*
WITH
</code></pre></div>
<h4 id=local-certificates>Generated Certificates for <code>localhost</code></h4>
<p>To generate a certificate authority (CA) and a certificate pair to be
used during local development, we use the <code>mkcert</code> <a href="https://github.com/FiloSottile/mkcert">tool</a>. Rather than
installing this CA on our system, we'll generate it in a Docker container
and bring the generated files back to our host operating system. The
<code>generate-tls-certs.sh</code> <a href="/code/generate-tls-certs.sh">script</a> can be used to generate four PEM
files</p>
<ul>
<li><code>localhost-cert.pem</code> <a href="/code/localhost-cert.pem">public certificate</a></li>
<li><code>localhost-key.pem</code> <a href="/code/localhost-key.pem">private key</a></li>
<li><code>rootCA-cert.pem</code> <a href="/code/rootCA-cert.pem">public certificate</a></li>
<li><code>rootCA-key.pem</code> <a href="/code/rootCA-key.pem">private key</a></li>
</ul>
<p>and this script itself relies on the <code>generate-tls-certs-on-alpine.sh</code>
<a href="/code/generate-tls-certs-on-alpine.sh">file</a>.</p>
<h4 id=warning-trust>Warning about <code>trust proxy</code></h4>
<p>Note that "trust proxy" <strong>requires</strong> that the server trusts the proxy that
it is communicating with. If the client communicates directly (rather than
through the proxy), the XFF header can be spoofed</p>
<div class=highlight><pre><span></span><code>$ curl http://localhost:3000
req.ip: "::1"
req.xff: undefined
$ curl \
> --header 'X-Forwarded-For: 198.51.100.22' \
> http://localhost:3000
req.ip: "198.51.100.22"
req.xff: "198.51.100.22"
</code></pre></div>
<h4 id=curl-flag>Why <code>--cacert</code> Flag</h4>
<p>The <code>--cacert</code> flag is required when using TLS to communicate with an
untrusted local server. If not provided requests will fail:</p>
<div class=highlight><pre><span></span><code>$ curl https://localhost:3443
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
</code></pre></div>
<p>This is because our private key / public certificate pair has been signed
by the CA we generated above, which is not in the root of trust for <code>curl</code>
(or for the OS).</p>
<hr><ol class=simple-footnotes><li id=sf-life-of-request-1>It was recent when I wrote this on July 27, 2020. <a href=#sf-life-of-request-1-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-2>See <a href="/code/server.js">source</a> for <code>server.js</code>. <a href=#sf-life-of-request-2-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-3>Running <code>server.js</code> will require
having <code>node</code> and <code>npm</code> installed, in a directory with a <code>package.json</code> file.
For our example we are using <code>node@12.14.1</code>, <code>npm@6.13.4</code> and installing
Express with <code>npm install express@4.17.1 --save-exact</code>. <a href=#sf-life-of-request-3-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-4>See <a href=#local-certificates>Generated Certificates</a> for
<code>localhost</code>. <a href=#sf-life-of-request-4-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-5>We <a href="https://caddyserver.com/v1/download">install</a> version 1 of <code>caddy</code>
with <code>http.proxyprotocol</code> enabled. The feature is <a href="https://github.com/mastercactapus/caddy-proxyprotocol/issues/9">not yet supported</a> in
version 2 of <code>caddy</code>. <a href=#sf-life-of-request-5-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-6>See
<a href="/code/tls.Caddyfile">source</a> for <code>tls.Caddyfile</code>. <a href=#sf-life-of-request-6-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-7>See
<a href=#curl-flag>Why</a> <code>--cacert</code> Flag. <a href=#sf-life-of-request-7-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-8>See <a href=#netcat-proxy-protocol>Observing PROXY Protocol</a>. <a href=#sf-life-of-request-8-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-9>See <a href="/code/proxy-protocol.Caddyfile">source</a> for
<code>proxy-protocol.Caddyfile</code>. <a href=#sf-life-of-request-9-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-10>See <a href="/code/wrapped-request.go">source</a> for <code>wrapped-request.go</code>. <a href=#sf-life-of-request-10-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-11>Sidecars are separate containers that belong to the same
Kubernetes pod. <a href=#sf-life-of-request-11-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-12>See <a href="/code/server-trust.js">source</a> for
<code>server-trust.js</code>. <a href=#sf-life-of-request-12-back class=simple-footnote-back>↩</a></li><li id=sf-life-of-request-13>See
<a href=#warning-trust>Warning about</a> <code>trust proxy</code>. <a href=#sf-life-of-request-13-back class=simple-footnote-back>↩</a></li></ol>Difference Between localhost and 0.0.0.02020-07-17T00:00:00-07:002020-07-17T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-07-17:/2020/07/loopback-vs-any-ip.html<blockquote>
<p><strong>Note</strong>: In a <code>docker</code> container, a server can only be available
<strong>outside of the container / pod</strong> if it is bound to the "any host"
IP<sup id=sf-loopback-vs-any-ip-1-back><a href=#sf-loopback-vs-any-ip-1 class=simple-footnote title='The "any host" IP is 0.0.0.0 for IPv4 and :: for IPv6'>1</a></sup>.
Binding a server to <code>localhost</code> / the loopback IP<sup id=sf-loopback-vs-any-ip-2-back><a href=#sf-loopback-vs-any-ip-2 class=simple-footnote title="The loopback IP is 127.0.0.1 for IPv4 and ::1 for IPv6.">2</a></sup> will mean the server is
only reachable within the container / pod.</p>
</blockquote>
<p>Consider the following Express …</p><blockquote>
<p><strong>Note</strong>: In a <code>docker</code> container, a server can only be available
<strong>outside of the container / pod</strong> if it is bound to the "any host"
IP<sup id=sf-loopback-vs-any-ip-1-back><a href=#sf-loopback-vs-any-ip-1 class=simple-footnote title='The "any host" IP is 0.0.0.0 for IPv4 and :: for IPv6'>1</a></sup>.
Binding a server to <code>localhost</code> / the loopback IP<sup id=sf-loopback-vs-any-ip-2-back><a href=#sf-loopback-vs-any-ip-2 class=simple-footnote title="The loopback IP is 127.0.0.1 for IPv4 and ::1 for IPv6.">2</a></sup> will mean the server is
only reachable within the container / pod.</p>
</blockquote>
<p>Consider the following Express application which binds to the default IP for
port 3000, explicitly binds to <code>127.0.0.1</code> for port 4000 and explicitly binds
to <code>0.0.0.0</code> for port 5000:</p>
<div class=highlight><pre><span></span><code><span class=c1>// index.js</span>
<span class=kd>const</span> <span class=nx>express</span> <span class=o>=</span> <span class=nx>require</span><span class=p>(</span><span class=s2>"express"</span><span class=p>);</span>
<span class=kd>const</span> <span class=nx>app</span> <span class=o>=</span> <span class=nx>express</span><span class=p>();</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>get</span><span class=p>(</span><span class=s2>"/"</span><span class=p>,</span> <span class=p>(</span><span class=nx>req</span><span class=p>,</span> <span class=nx>res</span><span class=p>)</span> <span class=p>=></span> <span class=nx>res</span><span class=p>.</span><span class=nx>send</span><span class=p>(</span><span class=s2>"Hello World!\n"</span><span class=p>));</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>listen</span><span class=p>(</span><span class=mf>3000</span><span class=p>,</span> <span class=p>()</span> <span class=p>=></span> <span class=nx>console</span><span class=p>.</span><span class=nx>log</span><span class=p>(</span><span class=s2>"Listening on port 3000"</span><span class=p>));</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>listen</span><span class=p>(</span><span class=mf>4000</span><span class=p>,</span> <span class=s2>"127.0.0.1"</span><span class=p>,</span> <span class=p>()</span> <span class=p>=></span> <span class=nx>console</span><span class=p>.</span><span class=nx>log</span><span class=p>(</span><span class=s2>"Listening on port 4000"</span><span class=p>));</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>listen</span><span class=p>(</span><span class=mf>5000</span><span class=p>,</span> <span class=s2>"0.0.0.0"</span><span class=p>,</span> <span class=p>()</span> <span class=p>=></span> <span class=nx>console</span><span class=p>.</span><span class=nx>log</span><span class=p>(</span><span class=s2>"Listening on port 5000"</span><span class=p>));</span>
</code></pre></div>
<p>We'll install <code>express</code> and run this application in a Docker container</p>
<div class=highlight><pre><span></span><code><span class=go>docker run \</span>
<span class=go> --name loopback_unreachable \</span>
<span class=go> --rm --detach \</span>
<span class=go> --publish 3001:3000 \</span>
<span class=go> --publish 4001:4000 \</span>
<span class=go> --publish 5001:5000 \</span>
<span class=go> --workdir /var/code \</span>
<span class=go> --volume $(pwd)/index.js:/var/code/index.js \</span>
<span class=go> node:12.18.1-alpine3.12 \</span>
<span class=go> /bin/sh -c 'npm install express@4.17.1 && node /var/code/index.js'</span>
</code></pre></div>
<p>From the <code>--publish</code> flags we can see the server ports from the container
have been exposed by adding one to each port value. Trying to hit these
ports on the host<sup id=sf-loopback-vs-any-ip-3-back><a href=#sf-loopback-vs-any-ip-3 class=simple-footnote title='To clarify, "on the host" is meant to distinguish from "inside the container".'>3</a></sup>, we can see port <code>4001</code> — the
one that is bound explicitly to <code>127.0.0.1</code> in the container — is
unreachable:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>curl http://localhost:3001
<span class=go>Hello World!</span>
<span class=gp>$ </span>curl http://localhost:4001
<span class=go>curl: (52) Empty reply from server</span>
<span class=gp>$ </span>curl http://localhost:5001
<span class=go>Hello World!</span>
</code></pre></div>
<p>Don't forget to clean up:</p>
<div class=highlight><pre><span></span><code><span class=go>docker rm --force loopback_unreachable</span>
</code></pre></div><ol class=simple-footnotes><li id=sf-loopback-vs-any-ip-1>The "any host" IP is <code>0.0.0.0</code> for IPv4 and <code>::</code> for IPv6 <a href=#sf-loopback-vs-any-ip-1-back class=simple-footnote-back>↩</a></li><li id=sf-loopback-vs-any-ip-2>The loopback IP is
<code>127.0.0.1</code> for IPv4 and <code>::1</code> for IPv6. <a href=#sf-loopback-vs-any-ip-2-back class=simple-footnote-back>↩</a></li><li id=sf-loopback-vs-any-ip-3>To clarify, "on the host" is meant to distinguish from
"inside the container". <a href=#sf-loopback-vs-any-ip-3-back class=simple-footnote-back>↩</a></li></ol>Isolating (Cordoning) a Misbehaving Pod2020-07-16T00:00:00-07:002020-07-16T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-07-16:/2020/07/cordon-pod.html<blockquote>
<p><strong>TL;DR</strong>: You can remove a misbehaving pod from a service without deleting
it. Use <code>kubectl label pod ... cyberdyne-service- ...</code> to remove a
label / labels. Once the labels are gone it will be removed from the
Kubernetes service that routes traffic to pods.</p>
</blockquote>
<p>When a Kubernetes <strong>node</strong> is misbehaving, it's common …</p><blockquote>
<p><strong>TL;DR</strong>: You can remove a misbehaving pod from a service without deleting
it. Use <code>kubectl label pod ... cyberdyne-service- ...</code> to remove a
label / labels. Once the labels are gone it will be removed from the
Kubernetes service that routes traffic to pods.</p>
</blockquote>
<p>When a Kubernetes <strong>node</strong> is misbehaving, it's common to cordon that
node via</p>
<div class="highlight"><pre><span></span><code><span class="go">kubectl cordon ip-10-10-9-94.ec2.internal</span>
</code></pre></div>
<p>It turns out, it's not as simple to do this for a misbehaving <strong>pod</strong>. In
order to do the same for a pod, we remove the labels used by the Kubernetes
service that routes traffic to pods via a selector and the Kubernetes
deployment that manages creation of pods, scaling, etc.</p>
<p>Per <a href="https://groups.google.com/g/kubernetes-dev/c/-sCoM9evaVg">recommendations</a> from <code>kubernetes-dev</code>, determine the pod labels that
keep it in a deployment</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>kubectl get pods --namespace cyberdyne --selector cyberdyne-service<span class="o">=</span>dhermes-echo
<span class="go">NAME READY STATUS RESTARTS AGE</span>
<span class="go">dhermes-echo-6c69bf4f49-6zbmx 3/3 Running 0 79m</span>
<span class="gp">$</span>
<span class="gp">$ </span>kubectl get deployment <span class="se">\</span>
<span class="gp">> </span> --namespace cyberdyne <span class="se">\</span>
<span class="gp">> </span> dhermes-echo <span class="se">\</span>
<span class="gp">> </span> --output go-template<span class="o">=</span><span class="s1">'{{ range $k, $v := .spec.selector.matchLabels }}{{ $k }} -> {{ $v }}{{ "\n" }}{{ end }}'</span>
<span class="go">cyberdyne-role -> service-instance</span>
<span class="go">cyberdyne-service -> dhermes-echo</span>
<span class="go">cyberdyne-service-env -> sandbox</span>
</code></pre></div>
<p>then remove one (or all) of those labels, this will bring up a new pod
and keep the old one running</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>kubectl label pod <span class="se">\</span>
<span class="gp">> </span> --namespace cyberdyne <span class="se">\</span>
<span class="gp">> </span> dhermes-echo-6c69bf4f49-6zbmx <span class="se">\</span>
<span class="gp">> </span> <span class="nv">frozen</span><span class="o">=</span>dhermes-experiment <span class="se">\</span>
<span class="gp">> </span> cyberdyne-role- <span class="se">\</span>
<span class="gp">> </span> cyberdyne-service- <span class="se">\</span>
<span class="gp">> </span> cyberdyne-service-env-
<span class="go">pod/dhermes-echo-6c69bf4f49-6zbmx labeled</span>
<span class="gp">$</span>
<span class="gp">$ </span>kubectl get pods --namespace cyberdyne --selector cyberdyne-service<span class="o">=</span>dhermes-echo
<span class="go">NAME READY STATUS RESTARTS AGE</span>
<span class="go">dhermes-echo-6c69bf4f49-8tmrf 3/3 Running 0 20s</span>
<span class="gp">$</span>
<span class="gp">$ </span>kubectl get pods --namespace cyberdyne --selector cyberdyne-deploy<span class="o">=</span>bcxsl9xf
<span class="go">NAME READY STATUS RESTARTS AGE</span>
<span class="go">dhermes-echo-6c69bf4f49-6zbmx 3/3 Running 0 86m</span>
<span class="go">dhermes-echo-6c69bf4f49-8tmrf 3/3 Running 0 51s</span>
</code></pre></div>
<p>and the service doesn't skip a beat</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>curl https://dhermes-echo.sandbox.k8s.invalid/headers
<span class="go">{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["curl/7.64.1"],"X-Forwarded-For":["10.131.12.77"],"X-Forwarded-Port":["443"],"X-Forwarded-Proto":["https"]}</span>
</code></pre></div>
<p>Additionally, the liveness and readiness probes can be removed from any
containers that have them, so the bad behavior can be left alone</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>kubectl edit pod --namespace cyberdyne dhermes-echo-6c69bf4f49-6zbmx
</code></pre></div>
<blockquote>
<p><strong>Tip</strong>: I usually set <code>KUBE_EDITOR=emacs</code> or <code>KUBE_EDITOR='code --wait'</code> when
running <code>kubectl edit</code>. The default editor it uses likely won't be what you
want.</p>
</blockquote>
<p>Don't forget to clean up the pod when done debugging</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>kubectl delete pod --namespace cyberdyne dhermes-echo-6c69bf4f49-6zbmx
</code></pre></div>ADDR vs. HOST2020-07-08T00:00:00-07:002020-07-08T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-07-08:/2020/07/addr-vs-host.html<blockquote>
<p><strong>TL;DR</strong>: Prefer inclusion of the protocol in configurable environment
variables</p>
<p><code>VAULT_ADDR=https://vault.sandbox.invalid:8200</code></p>
<p>over</p>
<p><code>VAULT_HOST=vault.sandbox.invalid</code></p>
<p>since this enables targeting a local server, e.g. <code>http://localhost:8200</code>
without any code changes.</p>
</blockquote>
<p>We utilize sandbox, staging and other siloed environments to test changes
before …</p><blockquote>
<p><strong>TL;DR</strong>: Prefer inclusion of the protocol in configurable environment
variables</p>
<p><code>VAULT_ADDR=https://vault.sandbox.invalid:8200</code></p>
<p>over</p>
<p><code>VAULT_HOST=vault.sandbox.invalid</code></p>
<p>since this enables targeting a local server, e.g. <code>http://localhost:8200</code>
without any code changes.</p>
</blockquote>
<p>We utilize sandbox, staging and other siloed environments to test changes
before they go to production. As a result, this means application code and
library code often needs to have hostnames that are configurable based on the
current environment. For example:</p>
<div class="highlight"><pre><span></span><code><span class="c1">// config.ts</span>
<span class="k">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">process</span> <span class="k">from</span> <span class="s2">"process"</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">VAULT_HOST</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">VAULT_HOST</span> <span class="o">||</span> <span class="s2">"vault.sandbox.invalid"</span><span class="p">;</span>
</code></pre></div>
<p>Once the hostname is specified, it's common to use it to form a base URL
or to form fully fledged URLs:</p>
<div class="highlight"><pre><span></span><code><span class="c1">// auth.ts</span>
<span class="k">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">secrets</span> <span class="k">from</span> <span class="s2">"some-internal-secrets-library"</span><span class="p">;</span>
<span class="k">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">config</span> <span class="k">from</span> <span class="s2">"./config"</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">CLIENT</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">secrets</span><span class="p">.</span><span class="nx">Client</span><span class="p">(</span><span class="sb">`https://</span><span class="si">${</span><span class="nx">config</span><span class="p">.</span><span class="nx">VAULT_HOST</span><span class="si">}</span><span class="sb">:8200`</span><span class="p">);</span>
</code></pre></div>
<p>However, this approach <strong>requires</strong> the full address to use the <code>https</code>
protocol. In deployed environments, this isn't a problem because we <strong>want</strong>
to be communicating over TLS / <code>https</code>. However, the <code>*_HOST</code> approach leaves
no room for swapping out for a locally running version of the given
dependency: <code>http://localhost:*</code>. (See <a href="/2020/07/running-vault-locally.html">Running <code>vault</code> Locally</a> for
an explanation of <strong>how</strong> to run such a dependency locally.)</p>
<p>When doing local development in one application it may be necessary to also run
a related application locally. (Even if not necessary, it can be quite
convenient, e.g. if doing development on an airplane or without internet
access.) To support this, the <code>*_ADDR</code> pattern can be used instead of the
<code>*_HOST</code> pattern:</p>
<div class="highlight"><pre><span></span><code><span class="c1">// config.ts</span>
<span class="k">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">process</span> <span class="k">from</span> <span class="s2">"process"</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">VAULT_HOST</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">VAULT_HOST</span> <span class="o">||</span> <span class="s2">"vault.sandbox.invalid"</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">VAULT_ADDR</span> <span class="o">=</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">VAULT_ADDR</span> <span class="o">||</span> <span class="sb">`https://</span><span class="si">${</span><span class="nx">VAULT_HOST</span><span class="si">}</span><span class="sb">:8200`</span><span class="p">;</span>
<span class="c1">// auth.ts</span>
<span class="k">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">secrets</span> <span class="k">from</span> <span class="s2">"some-internal-secrets-library"</span><span class="p">;</span>
<span class="k">import</span> <span class="o">*</span> <span class="kr">as</span> <span class="nx">config</span> <span class="k">from</span> <span class="s2">"./config"</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">CLIENT</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">secrets</span><span class="p">.</span><span class="nx">Client</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">VAULT_ADDR</span><span class="p">);</span>
</code></pre></div>Running vault Locally2020-07-07T00:00:00-07:002020-07-07T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-07-07:/2020/07/running-vault-locally.html<p>In order to run <code>vault</code> locally (I did this because I was on an airplane),
first start the server with a known root token</p>
<div class="highlight"><pre><span></span><code><span class="go">export VAULT_TOKEN=root VAULT_ADDR=http://localhost:8200</span>
<span class="go">vault server -dev -dev-root-token-id="${VAULT_TOKEN}"</span>
<span class="go">vault version # As a baseline, this is the version of `vault` I am using …</span></code></pre></div><p>In order to run <code>vault</code> locally (I did this because I was on an airplane),
first start the server with a known root token</p>
<div class="highlight"><pre><span></span><code><span class="go">export VAULT_TOKEN=root VAULT_ADDR=http://localhost:8200</span>
<span class="go">vault server -dev -dev-root-token-id="${VAULT_TOKEN}"</span>
<span class="go">vault version # As a baseline, this is the version of `vault` I am using</span>
<span class="gp"># </span>Vault v1.4.2 <span class="o">(</span><span class="s1">'18f1c494be8b06788c2fdda1a4296eb3c4b174ce+CHANGES'</span><span class="o">)</span>
</code></pre></div>
<p>then replace the secrets engine with KVv1 (which is what we use at Blend at
the time of this writing)</p>
<div class="highlight"><pre><span></span><code><span class="go">vault secrets disable secret</span>
<span class="go">vault secrets enable -path=secret -version=1 kv</span>
</code></pre></div>
<p>and finally seed any secrets that we'll use, for example</p>
<div class="highlight"><pre><span></span><code><span class="go">vault write \</span>
<span class="go"> secret/dev/service/deployment/cheese/default/BOARD_CREDENTIALS \</span>
<span class="go"> value=joe@mail.invalid:s33krit</span>
</code></pre></div>
<h3>Docker</h3>
<p>If you don't have <code>vault</code> installed or want to avoid forgetting that you've
got a <code>vault</code> server running, you can use <code>docker</code>.</p>
<div class="highlight"><pre><span></span><code><span class="go">docker run \</span>
<span class="go"> --rm \</span>
<span class="go"> --interactive --tty \</span>
<span class="go"> --name vault-dev-server \</span>
<span class="go"> --publish 8200:8200 \</span>
<span class="go"> --cap-add IPC_LOCK \</span>
<span class="go"> --env VAULT_DEV_ROOT_TOKEN_ID=root \</span>
<span class="go"> vault:1.4.1</span>
</code></pre></div>
<p>and then the same commands can be run to put it in KVv1 mode.</p>Express Trust Proxy2020-05-14T00:00:00-07:002020-05-14T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-05-14:/2020/05/trust-proxy.html<h3>Why?</h3>
<p>Using <code>app.use('trust proxy', true)</code> is likely too permissive, this post
explains concretely why.</p>
<h3>Example Applications</h3>
<p>Consider two Express applications <code>index-first.js</code> that uses
<code>app.set("trust proxy", true)</code></p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>express</span> <span class=o>=</span> <span class=nx>require</span><span class=p>(</span><span class=s2>"express"</span><span class=p>);</span>
<span class=kd>const</span> <span class=nx>app</span> <span class=o>=</span> <span class=nx>express</span><span class=p>();</span>
<span class=kd>const</span> <span class=nx>port</span> <span class=o>=</span> <span class=mf>3000</span><span class=p>;</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>set</span><span class=p>(</span><span class=s2>"trust proxy"</span><span class=p>,</span> <span class=kc>true</span><span class=p>);</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>get</span><span class=p>(</span><span class=s2>"/"</span><span class=p>,</span> <span class=p>(</span><span class=nx>req</span><span class=p>,</span> <span class=nx>res …</span></code></pre></div><h3>Why?</h3>
<p>Using <code>app.use('trust proxy', true)</code> is likely too permissive, this post
explains concretely why.</p>
<h3>Example Applications</h3>
<p>Consider two Express applications <code>index-first.js</code> that uses
<code>app.set("trust proxy", true)</code></p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>express</span> <span class=o>=</span> <span class=nx>require</span><span class=p>(</span><span class=s2>"express"</span><span class=p>);</span>
<span class=kd>const</span> <span class=nx>app</span> <span class=o>=</span> <span class=nx>express</span><span class=p>();</span>
<span class=kd>const</span> <span class=nx>port</span> <span class=o>=</span> <span class=mf>3000</span><span class=p>;</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>set</span><span class=p>(</span><span class=s2>"trust proxy"</span><span class=p>,</span> <span class=kc>true</span><span class=p>);</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>get</span><span class=p>(</span><span class=s2>"/"</span><span class=p>,</span> <span class=p>(</span><span class=nx>req</span><span class=p>,</span> <span class=nx>res</span><span class=p>)</span> <span class=p>=></span>
<span class=nx>res</span><span class=p>.</span><span class=nx>send</span><span class=p>(</span>
<span class=p>[</span>
<span class=s2>"req.ip: "</span><span class=p>,</span>
<span class=nx>JSON</span><span class=p>.</span><span class=nx>stringify</span><span class=p>(</span><span class=nx>req</span><span class=p>.</span><span class=nx>ip</span><span class=p>),</span>
<span class=s2>"\nreq.xff: "</span><span class=p>,</span>
<span class=nx>JSON</span><span class=p>.</span><span class=nx>stringify</span><span class=p>(</span><span class=nx>req</span><span class=p>.</span><span class=nx>headers</span><span class=p>[</span><span class=s2>"x-forwarded-for"</span><span class=p>]),</span>
<span class=p>].</span><span class=nx>join</span><span class=p>(</span><span class=s2>""</span><span class=p>)</span>
<span class=p>)</span>
<span class=p>);</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>listen</span><span class=p>(</span><span class=nx>port</span><span class=p>,</span> <span class=p>()</span> <span class=p>=></span> <span class=nx>console</span><span class=p>.</span><span class=nx>log</span><span class=p>(</span><span class=sb>`Example app listening on port </span><span class=si>${</span><span class=nx>port</span><span class=si>}</span><span class=sb>!`</span><span class=p>));</span>
</code></pre></div>
<p>and <code>index-last.js</code> that uses <code>app.set("trust proxy", 1)</code></p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>express</span> <span class=o>=</span> <span class=nx>require</span><span class=p>(</span><span class=s2>"express"</span><span class=p>);</span>
<span class=kd>const</span> <span class=nx>app</span> <span class=o>=</span> <span class=nx>express</span><span class=p>();</span>
<span class=kd>const</span> <span class=nx>port</span> <span class=o>=</span> <span class=mf>3001</span><span class=p>;</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>set</span><span class=p>(</span><span class=s2>"trust proxy"</span><span class=p>,</span> <span class=mf>1</span><span class=p>);</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>get</span><span class=p>(</span><span class=s2>"/"</span><span class=p>,</span> <span class=p>(</span><span class=nx>req</span><span class=p>,</span> <span class=nx>res</span><span class=p>)</span> <span class=p>=></span>
<span class=nx>res</span><span class=p>.</span><span class=nx>send</span><span class=p>(</span>
<span class=p>[</span>
<span class=s2>"req.ip: "</span><span class=p>,</span>
<span class=nx>JSON</span><span class=p>.</span><span class=nx>stringify</span><span class=p>(</span><span class=nx>req</span><span class=p>.</span><span class=nx>ip</span><span class=p>),</span>
<span class=s2>"\nreq.xff: "</span><span class=p>,</span>
<span class=nx>JSON</span><span class=p>.</span><span class=nx>stringify</span><span class=p>(</span><span class=nx>req</span><span class=p>.</span><span class=nx>headers</span><span class=p>[</span><span class=s2>"x-forwarded-for"</span><span class=p>]),</span>
<span class=p>].</span><span class=nx>join</span><span class=p>(</span><span class=s2>""</span><span class=p>)</span>
<span class=p>)</span>
<span class=p>);</span>
<span class=nx>app</span><span class=p>.</span><span class=nx>listen</span><span class=p>(</span><span class=nx>port</span><span class=p>,</span> <span class=p>()</span> <span class=p>=></span> <span class=nx>console</span><span class=p>.</span><span class=nx>log</span><span class=p>(</span><span class=sb>`Example app listening on port </span><span class=si>${</span><span class=nx>port</span><span class=si>}</span><span class=sb>!`</span><span class=p>));</span>
</code></pre></div>
<h3>Incoming Requests</h3>
<p>We can run both Express applications on ports 3000 and 3001</p>
<div class=highlight><pre><span></span><code>$ node index-first.js
Example app listening on port <span class=m>3000</span>!
$ node index-last.js
Example app listening on port <span class=m>3001</span>!
</code></pre></div>
<h4>Plain HTTP</h4>
<h5>With <code>app.set("trust proxy", true)</code></h5>
<p><strong>Observe</strong>: the <code>req.ip</code> value will always be the <strong>first</strong> / <strong>leftmost</strong>
value in the <code>X-Forwarded-For</code> header (if provided), and falls back to the
IP on the socket (<code>::1</code> is the IPv6 loopback / <code>localhost</code>) if the header
is absent:</p>
<div class=highlight><pre><span></span><code>$ curl http://localhost:3000
req.ip: <span class=s2>"::1"</span>
req.xff: undefined
$ curl --header <span class=s1>'X-Forwarded-For: 127.0.0.2'</span> http://localhost:3000
req.ip: <span class=s2>"127.0.0.2"</span>
req.xff: <span class=s2>"127.0.0.2"</span>
$ curl --header <span class=s1>'X-Forwarded-For: 127.0.0.3,127.0.0.2'</span> http://localhost:3000
req.ip: <span class=s2>"127.0.0.3"</span>
req.xff: <span class=s2>"127.0.0.3,127.0.0.2"</span>
$ curl --header <span class=s1>'X-Forwarded-For: 127.0.0.4,127.0.0.3,127.0.0.2'</span> http://localhost:3000
req.ip: <span class=s2>"127.0.0.4"</span>
req.xff: <span class=s2>"127.0.0.4,127.0.0.3,127.0.0.2"</span>
</code></pre></div>
<p>This means if a <strong>client</strong> provides an arbitrary / spoofed header they can
place any IP they like in <code>req.ip</code>.</p>
<h5>With <code>app.set("trust proxy", 1)</code></h5>
<p><strong>Observe</strong>: the <code>req.ip</code> value will always be the <strong>last</strong> / <strong>rightmost</strong>
value in the <code>X-Forwarded-For</code> header (if provided), and falls back to the
IP on the socket (<code>::1</code> is the IPv6 loopback / <code>localhost</code>) if the header
is absent:</p>
<div class=highlight><pre><span></span><code>$ curl http://localhost:3001
req.ip: <span class=s2>"::1"</span>
req.xff: undefined
$ curl --header <span class=s1>'X-Forwarded-For: 127.0.0.2'</span> http://localhost:3001
req.ip: <span class=s2>"127.0.0.2"</span>
req.xff: <span class=s2>"127.0.0.2"</span>
$ curl --header <span class=s1>'X-Forwarded-For: 127.0.0.3,127.0.0.2'</span> http://localhost:3001
req.ip: <span class=s2>"127.0.0.2"</span>
req.xff: <span class=s2>"127.0.0.3,127.0.0.2"</span>
$ curl --header <span class=s1>'X-Forwarded-For: 127.0.0.4,127.0.0.3,127.0.0.2'</span> http://localhost:3001
req.ip: <span class=s2>"127.0.0.2"</span>
req.xff: <span class=s2>"127.0.0.4,127.0.0.3,127.0.0.2"</span>
</code></pre></div>
<h4>HTTPS: Behind TLS Proxy</h4>
<p>We can use Caddy, NGINX, HAProxy or a similar tool as a TLS reverse proxy and
locally put our services behind this proxy<sup id=sf-trust-proxy-1-back><a href=#sf-trust-proxy-1 class=simple-footnote title="For the proxy, I used a certificate localhost-cert.pem and key localhost-key.pem that are signed by a local root CA.">1</a></sup>. We can use port 8443 to proxy
port 3000 (<code>index-first.js</code>) and port 9443 to proxy port 3001
(<code>index-last.js</code>).</p>
<p>When calling these TLS servers, we use <code>curl --haproxy-protocol</code> to
"simulate" the <a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html">PROXY protocol</a> prefix at the beginning of the TCP
data stream.</p>
<h5>With <code>app.set("trust proxy", true)</code></h5>
<p><strong>Observe</strong>: the TLS reverse proxy modifies the incoming <code>X-Forwarded-For</code>
header by <strong>appending</strong> the caller's IP (determined by the PROXY protocol
prefix). If the <code>X-Forwarded-For</code> is absent, the caller's IP will be the
only entry in it.</p>
<div class=highlight><pre><span></span><code>$ curl <span class=se>\</span>
> --haproxy-protocol <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> https://localhost:8443
req.ip: <span class=s2>"::1"</span>
req.xff: <span class=s2>"::1"</span>
$
$ curl <span class=se>\</span>
> --haproxy-protocol <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> --header <span class=s1>'X-Forwarded-For: 127.0.0.2'</span> <span class=se>\</span>
> https://localhost:8443
req.ip: <span class=s2>"127.0.0.2"</span>
req.xff: <span class=s2>"127.0.0.2, ::1"</span>
$
$ curl <span class=se>\</span>
> --haproxy-protocol <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> --header <span class=s1>'X-Forwarded-For: 127.0.0.3,127.0.0.2'</span> <span class=se>\</span>
> https://localhost:8443
req.ip: <span class=s2>"127.0.0.3"</span>
req.xff: <span class=s2>"127.0.0.3,127.0.0.2, ::1"</span>
$
$ curl <span class=se>\</span>
> --haproxy-protocol <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> --header <span class=s1>'X-Forwarded-For: 127.0.0.4,127.0.0.3,127.0.0.2'</span> <span class=se>\</span>
> https://localhost:8443
req.ip: <span class=s2>"127.0.0.4"</span>
req.xff: <span class=s2>"127.0.0.4,127.0.0.3,127.0.0.2, ::1"</span>
$
$ <span class=c1># Drop the PROXY protocol prefix</span>
$ curl <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> --header <span class=s1>'X-Forwarded-For: 127.0.0.4,127.0.0.3,127.0.0.2'</span> <span class=se>\</span>
> https://localhost:8443
req.ip: <span class=s2>"127.0.0.4"</span>
req.xff: <span class=s2>"127.0.0.4,127.0.0.3,127.0.0.2, ::1"</span>
</code></pre></div>
<p>As before since the <strong>first</strong> entry will be used, the PROXY protocol provided
IP will only be used if the client <strong>did not</strong> send an <code>X-Forwarded-For</code>
header.</p>
<h5>With <code>app.set("trust proxy", 1)</code></h5>
<div class=highlight><pre><span></span><code>$ curl <span class=se>\</span>
> --haproxy-protocol <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> https://localhost:9443
req.ip: <span class=s2>"::1"</span>
req.xff: <span class=s2>"::1"</span>
$
$ curl <span class=se>\</span>
> --haproxy-protocol <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> --header <span class=s1>'X-Forwarded-For: 127.0.0.2'</span> <span class=se>\</span>
> https://localhost:9443
req.ip: <span class=s2>"::1"</span>
req.xff: <span class=s2>"127.0.0.2, ::1"</span>
$
$ curl <span class=se>\</span>
> --haproxy-protocol <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> --header <span class=s1>'X-Forwarded-For: 127.0.0.3,127.0.0.2'</span> <span class=se>\</span>
> https://localhost:9443
req.ip: <span class=s2>"::1"</span>
req.xff: <span class=s2>"127.0.0.3,127.0.0.2, ::1"</span>
$
$ curl <span class=se>\</span>
> --haproxy-protocol <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> --header <span class=s1>'X-Forwarded-For: 127.0.0.4,127.0.0.3,127.0.0.2'</span> <span class=se>\</span>
> https://localhost:9443
req.ip: <span class=s2>"::1"</span>
req.xff: <span class=s2>"127.0.0.4,127.0.0.3,127.0.0.2, ::1"</span>
$
$ <span class=c1># Drop the PROXY protocol prefix</span>
$ curl <span class=se>\</span>
> --cacert ./rootCA-cert.pem <span class=se>\</span>
> --header <span class=s1>'X-Forwarded-For: 127.0.0.4,127.0.0.3,127.0.0.2'</span> <span class=se>\</span>
> https://localhost:9443
req.ip: <span class=s2>"::1"</span>
req.xff: <span class=s2>"127.0.0.4,127.0.0.3,127.0.0.2, ::1"</span>
</code></pre></div>
<h5>Simulating an AWS ELB PROXY Protocol</h5>
<p>Using <code>curl --proxy-protocol</code> didn't provide much value because the
"simulated" client IP was <code>::1</code>.</p>
<p>To really drive the point home, we can use the Python script
<code>haproxy_client.py</code> to customize the PROXY protocol prefix by prepending
<code>PROXY TCP4 198.51.100.22 203.0.113.7 35646 80\r\n</code> before sending the
request over TLS:</p>
<div class=highlight><pre><span></span><code><span class=kn>import</span> <span class=nn>socket</span>
<span class=kn>import</span> <span class=nn>ssl</span>
<span class=kn>import</span> <span class=nn>sys</span>
<span class=k>def</span> <span class=nf>main</span><span class=p>():</span>
<span class=n>port</span> <span class=o>=</span> <span class=s2>"8443"</span> <span class=k>if</span> <span class=nb>len</span><span class=p>(</span><span class=n>sys</span><span class=o>.</span><span class=n>argv</span><span class=p>)</span> <span class=o><</span> <span class=mi>2</span> <span class=k>else</span> <span class=n>sys</span><span class=o>.</span><span class=n>argv</span><span class=p>[</span><span class=mi>1</span><span class=p>]</span>
<span class=n>port_int</span> <span class=o>=</span> <span class=nb>int</span><span class=p>(</span><span class=n>port</span><span class=p>)</span>
<span class=n>port</span> <span class=o>=</span> <span class=n>port</span><span class=o>.</span><span class=n>encode</span><span class=p>(</span><span class=s2>"ascii"</span><span class=p>)</span> <span class=c1># `bytes`</span>
<span class=n>context</span> <span class=o>=</span> <span class=n>ssl</span><span class=o>.</span><span class=n>create_default_context</span><span class=p>(</span><span class=n>cafile</span><span class=o>=</span><span class=s2>"./rootCA-cert.pem"</span><span class=p>)</span>
<span class=n>haproxy_prefix</span> <span class=o>=</span> <span class=sa>b</span><span class=s2>"PROXY TCP4 198.51.100.22 203.0.113.7 35646 80</span><span class=se>\r\n</span><span class=s2>"</span>
<span class=n>http_body</span> <span class=o>=</span> <span class=sa>b</span><span class=s2>"</span><span class=se>\r\n</span><span class=s2>"</span><span class=o>.</span><span class=n>join</span><span class=p>(</span>
<span class=p>[</span>
<span class=sa>b</span><span class=s2>"GET / HTTP/1.1"</span><span class=p>,</span>
<span class=sa>b</span><span class=s2>"Host: localhost:"</span> <span class=o>+</span> <span class=n>port</span><span class=p>,</span>
<span class=sa>b</span><span class=s2>"User-Agent: python-raw-socket"</span><span class=p>,</span>
<span class=sa>b</span><span class=s2>"X-Forwarded-For: 127.0.0.4,127.0.0.3,127.0.0.2"</span><span class=p>,</span>
<span class=sa>b</span><span class=s2>"Accept: */*"</span><span class=p>,</span>
<span class=sa>b</span><span class=s2>""</span><span class=p>,</span>
<span class=sa>b</span><span class=s2>""</span><span class=p>,</span>
<span class=p>]</span>
<span class=p>)</span>
<span class=k>with</span> <span class=n>socket</span><span class=o>.</span><span class=n>create_connection</span><span class=p>((</span><span class=s2>"localhost"</span><span class=p>,</span> <span class=n>port_int</span><span class=p>))</span> <span class=k>as</span> <span class=n>sock</span><span class=p>:</span>
<span class=n>bytes_sent</span> <span class=o>=</span> <span class=n>sock</span><span class=o>.</span><span class=n>send</span><span class=p>(</span><span class=n>haproxy_prefix</span><span class=p>)</span>
<span class=k>assert</span> <span class=n>bytes_sent</span> <span class=o>==</span> <span class=nb>len</span><span class=p>(</span><span class=n>haproxy_prefix</span><span class=p>)</span>
<span class=k>with</span> <span class=n>context</span><span class=o>.</span><span class=n>wrap_socket</span><span class=p>(</span><span class=n>sock</span><span class=p>,</span> <span class=n>server_hostname</span><span class=o>=</span><span class=s2>"localhost"</span><span class=p>)</span> <span class=k>as</span> <span class=n>ssock</span><span class=p>:</span>
<span class=n>bytes_sent</span> <span class=o>=</span> <span class=n>ssock</span><span class=o>.</span><span class=n>send</span><span class=p>(</span><span class=n>http_body</span><span class=p>)</span>
<span class=k>assert</span> <span class=n>bytes_sent</span> <span class=o>==</span> <span class=nb>len</span><span class=p>(</span><span class=n>http_body</span><span class=p>)</span>
<span class=n>response_data</span> <span class=o>=</span> <span class=n>ssock</span><span class=o>.</span><span class=n>read</span><span class=p>(</span><span class=mi>1024</span><span class=p>)</span>
<span class=k>assert</span> <span class=nb>len</span><span class=p>(</span><span class=n>response_data</span><span class=p>)</span> <span class=o><</span> <span class=mi>1024</span>
<span class=nb>print</span><span class=p>(</span><span class=n>response_data</span><span class=o>.</span><span class=n>decode</span><span class=p>(</span><span class=s2>"ascii"</span><span class=p>))</span>
<span class=k>if</span> <span class=vm>__name__</span> <span class=o>==</span> <span class=s2>"__main__"</span><span class=p>:</span>
<span class=n>main</span><span class=p>()</span>
</code></pre></div>
<p>Running it against our two TLS ports we see the difference between the spoofed
"first" IP <code>127.0.0.4</code> in the <code>X-Forwarded-For</code> header and our desired client
IP (<code>198.51.100.22</code>) from the PROXY protocol prefix line</p>
<div class=highlight><pre><span></span><code>$ python haproxy_client.py <span class=m>8443</span>
HTTP/1.1 <span class=m>200</span> OK
Content-Length: <span class=m>76</span>
Content-Type: text/html<span class=p>;</span> <span class=nv>charset</span><span class=o>=</span>utf-8
Date: Mon, <span class=m>30</span> Mar <span class=m>2020</span> <span class=m>01</span>:25:11 GMT
Etag: W/<span class=s2>"4c-o7XjqzEh2LNIL5fg9aGvOinphjw"</span>
X-Powered-By: Express
req.ip: <span class=s2>"127.0.0.4"</span>
req.xff: <span class=s2>"127.0.0.4,127.0.0.3,127.0.0.2, 198.51.100.22"</span>
$
$ python haproxy_client.py <span class=m>9443</span>
HTTP/1.1 <span class=m>200</span> OK
Content-Length: <span class=m>80</span>
Content-Type: text/html<span class=p>;</span> <span class=nv>charset</span><span class=o>=</span>utf-8
Date: Mon, <span class=m>30</span> Mar <span class=m>2020</span> <span class=m>01</span>:25:06 GMT
Etag: W/<span class=s2>"50-7DCPwCaoMhDpTeV3xU491pqi5q4"</span>
X-Powered-By: Express
req.ip: <span class=s2>"198.51.100.22"</span>
req.xff: <span class=s2>"127.0.0.4,127.0.0.3,127.0.0.2, 198.51.100.22"</span>
</code></pre></div><ol class=simple-footnotes><li id=sf-trust-proxy-1>For the proxy, I used a
<a href="/code/localhost-cert.pem">certificate</a> <code>localhost-cert.pem</code> and <a href="/code/localhost-key.pem">key</a> <code>localhost-key.pem</code> that
are signed by a local <a href="/code/rootCA-cert.pem">root CA</a>. <a href=#sf-trust-proxy-1-back class=simple-footnote-back>↩</a></li></ol>A Threadsafe Connection Pool for Requests2020-04-22T00:00:00-07:002020-04-22T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2020-04-22:/2020/04/threadsafe-connection-pool.html<p>I've been load testing quite a bit recently. So far I've been impressed by the
<code>wrk</code> <a href="https://github.com/wg/wrk">project's</a> use of sockets to pour on a ridiculously high amount of
load. When I had stretched the system under load <strong>past</strong> its limits, finding
the <code>fortio</code> <a href="https://github.com/fortio/fortio">project</a> was a breath of fresh air …</p><p>I've been load testing quite a bit recently. So far I've been impressed by the
<code>wrk</code> <a href="https://github.com/wg/wrk">project's</a> use of sockets to pour on a ridiculously high amount of
load. When I had stretched the system under load <strong>past</strong> its limits, finding
the <code>fortio</code> <a href="https://github.com/fortio/fortio">project</a> was a breath of fresh air, in particular because of
the inclusion of a <code>-qps</code> flag to control the rate (and duration) of a load
test.</p>
<p>So what does this have to do with <code>requests</code>? These load testing tools (and
many others) are great if you know what to expect of your failures, but I was
load testing to debug a problem. I wanted a way to <strong>keep</strong> all failed
responses and inspect them after the fact; I wanted an <strong>escape hatch</strong> into
the event loop firing off requests.</p>
<p>Motivated by <code>wrk</code>, I wanted to utilize a large-ish thread pool all sharing
a connection pool. A shared connection pool enables testing of re-used TCP
sockets and can generate more load since TLS negotiation can be re-used. Using
the <code>select</code> <a href="https://docs.python.org/3/library/select.html">package</a> and low-level <a href="https://docs.python.org/3/library/socket.html">socket</a> objects to accomplish this
task likely would've given maximal throughput but the sheer amount of work
required was not worth it, especially because a modest few hundred requests
per second was all I was looking for (i.e. a controlled but steady flow of
traffic). So I sought to put the über-popular <code>requests</code><sup id=sf-threadsafe-connection-pool-1-back><a href=#sf-threadsafe-connection-pool-1 class=simple-footnote title="Version 2.23.0, running Python 3.8.2 on macOS 10.15.4 as of this writing">1</a></sup> <a href="https://requests.readthedocs.io/en/master/">package</a> to the task.</p>
<h3 id=contents>Contents</h3>
<ul>
<li><a href=#zero-modification-approach>Zero Modification Approach</a></li>
<li><a href=#zero-correctness>Zero Correctness</a></li>
<li><a href=#queue-and-per-thread-pool>Queue and Per-thread Pool</a></li>
<li><a href=#verification>Verification</a></li>
</ul>
<h3 id=zero-modification-approach>Zero Modification Approach</h3>
<p>Based on a very popular StackOverflow <a href="https://stackoverflow.com/q/18188044/1068170">question</a>, I knew
<code>requests.Session()</code> wasn't "really" threadsafe, but I figured I'd give it
a try anyhow. By using a <code>requests</code> adapter, a connection pool size can be
specified</p>
<div class=highlight><pre><span></span><code><span class=kn>import</span> <span class=nn>requests</span>
<span class=k>def</span> <span class=nf>connection_pool</span><span class=p>(</span><span class=n>size</span><span class=p>):</span>
<span class=n>session</span> <span class=o>=</span> <span class=n>requests</span><span class=o>.</span><span class=n>Session</span><span class=p>()</span>
<span class=n>adapter</span> <span class=o>=</span> <span class=n>requests</span><span class=o>.</span><span class=n>adapters</span><span class=o>.</span><span class=n>HTTPAdapter</span><span class=p>(</span>
<span class=n>pool_connections</span><span class=o>=</span><span class=n>size</span><span class=p>,</span> <span class=n>pool_maxsize</span><span class=o>=</span><span class=n>size</span>
<span class=p>)</span>
<span class=n>session</span><span class=o>.</span><span class=n>mount</span><span class=p>(</span><span class=s2>"http://"</span><span class=p>,</span> <span class=n>adapter</span><span class=p>)</span>
<span class=n>session</span><span class=o>.</span><span class=n>mount</span><span class=p>(</span><span class=s2>"https://"</span><span class=p>,</span> <span class=n>adapter</span><span class=p>)</span>
<span class=k>return</span> <span class=n>session</span>
</code></pre></div>
<p>To take it for a test drive, I spun up 4 threads to share a connection pool
of size 2 and at first things looked just fine. Running</p>
<div class=highlight><pre><span></span><code><span class=kn>import</span> <span class=nn>threading</span>
<span class=n>URL</span> <span class=o>=</span> <span class=s2>"https://www.google.com/"</span>
<span class=k>def</span> <span class=nf>make_request</span><span class=p>(</span><span class=n>i</span><span class=p>,</span> <span class=n>pool</span><span class=p>):</span>
<span class=n>response</span> <span class=o>=</span> <span class=n>pool</span><span class=o>.</span><span class=n>get</span><span class=p>(</span><span class=n>URL</span><span class=p>)</span>
<span class=nb>print</span><span class=p>(</span><span class=sa>f</span><span class=s2>"</span><span class=si>{</span><span class=n>i</span><span class=si>}</span><span class=s2> Status Code: </span><span class=si>{</span><span class=n>response</span><span class=o>.</span><span class=n>status_code</span><span class=si>}</span><span class=s2>"</span><span class=p>)</span>
<span class=k>def</span> <span class=nf>spawn_threads</span><span class=p>(</span><span class=n>pool_size</span><span class=p>,</span> <span class=n>thread_count</span><span class=p>):</span>
<span class=n>pool</span> <span class=o>=</span> <span class=n>connection_pool</span><span class=p>(</span><span class=n>pool_size</span><span class=p>)</span>
<span class=n>threads</span> <span class=o>=</span> <span class=p>[]</span>
<span class=k>for</span> <span class=n>i</span> <span class=ow>in</span> <span class=nb>range</span><span class=p>(</span><span class=n>thread_count</span><span class=p>):</span>
<span class=n>thread</span> <span class=o>=</span> <span class=n>threading</span><span class=o>.</span><span class=n>Thread</span><span class=p>(</span><span class=n>target</span><span class=o>=</span><span class=n>make_request</span><span class=p>,</span> <span class=n>args</span><span class=o>=</span><span class=p>(</span><span class=n>i</span><span class=p>,</span> <span class=n>pool</span><span class=p>))</span>
<span class=n>thread</span><span class=o>.</span><span class=n>start</span><span class=p>()</span>
<span class=n>threads</span><span class=o>.</span><span class=n>append</span><span class=p>(</span><span class=n>thread</span><span class=p>)</span>
<span class=k>return</span> <span class=n>threads</span>
<span class=k>def</span> <span class=nf>main</span><span class=p>():</span>
<span class=n>threads</span> <span class=o>=</span> <span class=n>spawn_threads</span><span class=p>(</span><span class=mi>2</span><span class=p>,</span> <span class=mi>4</span><span class=p>)</span>
<span class=k>for</span> <span class=n>thread</span> <span class=ow>in</span> <span class=n>threads</span><span class=p>:</span>
<span class=n>thread</span><span class=o>.</span><span class=n>join</span><span class=p>()</span>
<span class=k>if</span> <span class=vm>__name__</span> <span class=o>==</span> <span class=s2>"__main__"</span><span class=p>:</span>
<span class=n>main</span><span class=p>()</span>
</code></pre></div>
<p>all 4 threads seem to do their work without interfering with one another</p>
<div class=highlight><pre><span></span><code><span class=mf>1</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>2</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>0</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>3</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
</code></pre></div>
<h3 id=zero-correctness>Zero Correctness</h3>
<p>To be sure, I added a response hook to actually verify the socket being used
on each request</p>
<div class=highlight><pre><span></span><code><span class=kn>import</span> <span class=nn>socket</span>
<span class=k>def</span> <span class=nf>make_response_hook</span><span class=p>(</span><span class=n>i</span><span class=p>):</span>
<span class=k>def</span> <span class=nf>response_hook</span><span class=p>(</span><span class=n>response</span><span class=p>,</span> <span class=o>**</span><span class=n>unused_kwargs</span><span class=p>):</span>
<span class=n>sock</span> <span class=o>=</span> <span class=n>socket</span><span class=o>.</span><span class=n>fromfd</span><span class=p>(</span>
<span class=n>response</span><span class=o>.</span><span class=n>raw</span><span class=o>.</span><span class=n>fileno</span><span class=p>(),</span> <span class=n>socket</span><span class=o>.</span><span class=n>AF_INET</span><span class=p>,</span> <span class=n>socket</span><span class=o>.</span><span class=n>SOCK_STREAM</span>
<span class=p>)</span>
<span class=n>client_ip</span><span class=p>,</span> <span class=n>port</span> <span class=o>=</span> <span class=n>sock</span><span class=o>.</span><span class=n>getsockname</span><span class=p>()</span>
<span class=nb>print</span><span class=p>(</span><span class=sa>f</span><span class=s2>"</span><span class=si>{</span><span class=n>i</span><span class=si>}</span><span class=s2> Socket client address: </span><span class=si>{</span><span class=n>client_ip</span><span class=si>}</span><span class=s2>:</span><span class=si>{</span><span class=n>port</span><span class=si>}</span><span class=s2>"</span><span class=p>)</span>
<span class=k>return</span> <span class=n>response_hook</span>
<span class=k>def</span> <span class=nf>make_request</span><span class=p>(</span><span class=n>i</span><span class=p>,</span> <span class=n>pool</span><span class=p>):</span>
<span class=n>response</span> <span class=o>=</span> <span class=n>pool</span><span class=o>.</span><span class=n>get</span><span class=p>(</span><span class=n>URL</span><span class=p>,</span> <span class=n>hooks</span><span class=o>=</span><span class=p>{</span><span class=s2>"response"</span><span class=p>:</span> <span class=n>make_response_hook</span><span class=p>(</span><span class=n>i</span><span class=p>)})</span>
<span class=nb>print</span><span class=p>(</span><span class=sa>f</span><span class=s2>"</span><span class=si>{</span><span class=n>i</span><span class=si>}</span><span class=s2> Status Code: </span><span class=si>{</span><span class=n>response</span><span class=o>.</span><span class=n>status_code</span><span class=si>}</span><span class=s2>"</span><span class=p>)</span>
</code></pre></div>
<p>After running this I confirmed that the threads were <strong>not</strong> sharing a pool
of (at most) 2 open TCP sockets:</p>
<div class=highlight><pre><span></span><code><span class=mf>0</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>50784</span>
<span class=mf>0</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>3</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>50786</span>
<span class=mf>3</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>2</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>50787</span>
<span class=mf>1</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>50785</span>
<span class=mf>1</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>2</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
</code></pre></div>
<p>To me, this indicates either <code>requests.Session</code> directly or some component
(e.g. the underlying <code>urllib3</code> <a href="https://urllib3.readthedocs.io/en/latest/">package</a>) is using thread local storage
for parts of the connection pool<sup id=sf-threadsafe-connection-pool-2-back><a href=#sf-threadsafe-connection-pool-2 class=simple-footnote title="I'd love to know more but was more focused on getting a working multithreaded connection pool.">2</a></sup>.
However, using a <strong>global</strong> lock on usage of the connection pool</p>
<div class=highlight><pre><span></span><code><span class=n>LOCK</span> <span class=o>=</span> <span class=n>threading</span><span class=o>.</span><span class=n>Lock</span><span class=p>()</span>
<span class=k>def</span> <span class=nf>make_request</span><span class=p>(</span><span class=n>i</span><span class=p>,</span> <span class=n>pool</span><span class=p>):</span>
<span class=k>with</span> <span class=n>LOCK</span><span class=p>:</span>
<span class=n>response</span> <span class=o>=</span> <span class=n>pool</span><span class=o>.</span><span class=n>get</span><span class=p>(</span><span class=n>URL</span><span class=p>,</span> <span class=n>hooks</span><span class=o>=</span><span class=p>{</span><span class=s2>"response"</span><span class=p>:</span> <span class=n>make_response_hook</span><span class=p>(</span><span class=n>i</span><span class=p>)})</span>
<span class=nb>print</span><span class=p>(</span><span class=sa>f</span><span class=s2>"</span><span class=si>{</span><span class=n>i</span><span class=si>}</span><span class=s2> Status Code: </span><span class=si>{</span><span class=n>response</span><span class=o>.</span><span class=n>status_code</span><span class=si>}</span><span class=s2>"</span><span class=p>)</span>
</code></pre></div>
<p>it is clear that the <strong>same</strong> socket is used for all requests</p>
<div class=highlight><pre><span></span><code><span class=mf>0</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51143</span>
<span class=mf>0</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>1</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51143</span>
<span class=mf>1</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>2</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51143</span>
<span class=mf>2</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>3</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51143</span>
<span class=mf>3</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
</code></pre></div>
<p>so there is some level of sharing across threads.</p>
<h3 id=queue-and-per-thread-pool>Queue and Per-thread Pool</h3>
<p>Since I couldn't directly rely on <code>requests.Session()</code> as a multithreaded
pool I sought to create one. I briefly looked into the
<code>requests_toolbelt.threaded.pool</code> <a href="https://toolbelt.readthedocs.io/en/latest/threading.html">module</a> but it also lacks the escape
hatch I was looking for.</p>
<p>Using a <strong>global</strong> lock as above completely defeats the point of concurrent
workers, so this is not an option. Requiring each thread to maintain its own
pool may be unnecessarily restrictive, but due to the state sharing issue each
of the <code>N</code> distinct connections will need an exclusive lock.</p>
<p>In order to simulate <code>N</code> locks while maintaining some modicum of throughput,
a <code>queue.Queue()</code> can be used:</p>
<div class=highlight><pre><span></span><code><span class=kn>import</span> <span class=nn>queue</span>
<span class=k>def</span> <span class=nf>threadsafe_pool</span><span class=p>(</span><span class=n>size</span><span class=p>):</span>
<span class=n>id_queue</span> <span class=o>=</span> <span class=n>queue</span><span class=o>.</span><span class=n>Queue</span><span class=p>(</span><span class=n>maxsize</span><span class=o>=</span><span class=n>size</span><span class=p>)</span>
<span class=n>connections</span> <span class=o>=</span> <span class=p>{}</span>
<span class=k>for</span> <span class=n>i</span> <span class=ow>in</span> <span class=nb>range</span><span class=p>(</span><span class=n>size</span><span class=p>):</span>
<span class=n>id_queue</span><span class=o>.</span><span class=n>put</span><span class=p>(</span><span class=n>i</span><span class=p>)</span>
<span class=n>connections</span><span class=p>[</span><span class=n>i</span><span class=p>]</span> <span class=o>=</span> <span class=n>connection_pool</span><span class=p>(</span><span class=mi>1</span><span class=p>)</span>
<span class=k>return</span> <span class=n>connections</span><span class=p>,</span> <span class=n>id_queue</span>
</code></pre></div>
<p>Rather than putting the <code>requests.Session()</code> objects directly into the queue,
a read-only dictionary can be shared across all threads. Putting this to use,
the connections and the queue can be passed to the <code>make_request()</code> thread
target. The worker can make a (blocking) <code>get()</code> for a connection ID from the
queue, keep it until the request has completed and place the connection ID back
on the queue for re-use:</p>
<div class=highlight><pre><span></span><code><span class=k>def</span> <span class=nf>make_request</span><span class=p>(</span><span class=n>i</span><span class=p>,</span> <span class=n>connections</span><span class=p>,</span> <span class=n>id_queue</span><span class=p>):</span>
<span class=n>connection_id</span> <span class=o>=</span> <span class=n>id_queue</span><span class=o>.</span><span class=n>get</span><span class=p>()</span>
<span class=n>connection</span> <span class=o>=</span> <span class=n>connections</span><span class=p>[</span><span class=n>connection_id</span><span class=p>]</span>
<span class=n>response</span> <span class=o>=</span> <span class=n>connection</span><span class=o>.</span><span class=n>get</span><span class=p>(</span><span class=n>URL</span><span class=p>,</span> <span class=n>hooks</span><span class=o>=</span><span class=p>{</span><span class=s2>"response"</span><span class=p>:</span> <span class=n>make_response_hook</span><span class=p>(</span><span class=n>i</span><span class=p>)})</span>
<span class=n>id_queue</span><span class=o>.</span><span class=n>task_done</span><span class=p>()</span>
<span class=n>id_queue</span><span class=o>.</span><span class=n>put</span><span class=p>(</span><span class=n>connection_id</span><span class=p>)</span>
<span class=nb>print</span><span class=p>(</span><span class=sa>f</span><span class=s2>"</span><span class=si>{</span><span class=n>i</span><span class=si>}</span><span class=s2> Status Code: </span><span class=si>{</span><span class=n>response</span><span class=o>.</span><span class=n>status_code</span><span class=si>}</span><span class=s2>"</span><span class=p>)</span>
</code></pre></div>
<h3 id=verification>Verification</h3>
<p>To see that this works as expected, the <code>spawn_threads()</code> helper can be
updated to pass along the connections and queue</p>
<div class=highlight><pre><span></span><code><span class=k>def</span> <span class=nf>spawn_threads</span><span class=p>(</span><span class=n>pool_size</span><span class=p>,</span> <span class=n>thread_count</span><span class=p>):</span>
<span class=n>connections</span><span class=p>,</span> <span class=n>id_queue</span> <span class=o>=</span> <span class=n>threadsafe_pool</span><span class=p>(</span><span class=n>pool_size</span><span class=p>)</span>
<span class=n>threads</span> <span class=o>=</span> <span class=p>[]</span>
<span class=k>for</span> <span class=n>i</span> <span class=ow>in</span> <span class=nb>range</span><span class=p>(</span><span class=n>thread_count</span><span class=p>):</span>
<span class=n>thread</span> <span class=o>=</span> <span class=n>threading</span><span class=o>.</span><span class=n>Thread</span><span class=p>(</span>
<span class=n>target</span><span class=o>=</span><span class=n>make_request</span><span class=p>,</span> <span class=n>args</span><span class=o>=</span><span class=p>(</span><span class=n>i</span><span class=p>,</span> <span class=n>connections</span><span class=p>,</span> <span class=n>id_queue</span><span class=p>)</span>
<span class=p>)</span>
<span class=n>thread</span><span class=o>.</span><span class=n>start</span><span class=p>()</span>
<span class=n>threads</span><span class=o>.</span><span class=n>append</span><span class=p>(</span><span class=n>thread</span><span class=p>)</span>
<span class=k>return</span> <span class=n>threads</span>
</code></pre></div>
<p>and running the code shows exactly 2 sockets were used (and re-used)</p>
<div class=highlight><pre><span></span><code><span class=mf>1</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51426</span>
<span class=mf>1</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>0</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51425</span>
<span class=mf>0</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>2</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51426</span>
<span class=mf>2</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>3</span> <span class=n>Socket</span> <span class=n>client</span> <span class=n>address</span><span class=p>:</span> <span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51425</span>
<span class=mf>3</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
</code></pre></div>
<p>Turning up the difficulty level a bit, the sockets used can be tracked
(utilizing the atomicity of <code>list.append()</code> in Python)</p>
<div class=highlight><pre><span></span><code><span class=n>SOCKET_PAIRS</span> <span class=o>=</span> <span class=p>[]</span>
<span class=k>def</span> <span class=nf>make_response_hook</span><span class=p>(</span><span class=n>i</span><span class=p>):</span>
<span class=k>def</span> <span class=nf>response_hook</span><span class=p>(</span><span class=n>response</span><span class=p>,</span> <span class=o>**</span><span class=n>unused_kwargs</span><span class=p>):</span>
<span class=n>sock</span> <span class=o>=</span> <span class=n>socket</span><span class=o>.</span><span class=n>fromfd</span><span class=p>(</span>
<span class=n>response</span><span class=o>.</span><span class=n>raw</span><span class=o>.</span><span class=n>fileno</span><span class=p>(),</span> <span class=n>socket</span><span class=o>.</span><span class=n>AF_INET</span><span class=p>,</span> <span class=n>socket</span><span class=o>.</span><span class=n>SOCK_STREAM</span>
<span class=p>)</span>
<span class=n>SOCKET_PAIRS</span><span class=o>.</span><span class=n>append</span><span class=p>(</span><span class=n>sock</span><span class=o>.</span><span class=n>getsockname</span><span class=p>())</span>
<span class=k>return</span> <span class=n>response_hook</span>
</code></pre></div>
<p>Using this, a histogram of the sockets</p>
<div class=highlight><pre><span></span><code><span class=kn>import</span> <span class=nn>collections</span>
<span class=k>def</span> <span class=nf>main</span><span class=p>():</span>
<span class=n>threads</span> <span class=o>=</span> <span class=n>spawn_threads</span><span class=p>(</span><span class=mi>5</span><span class=p>,</span> <span class=mi>256</span><span class=p>)</span>
<span class=k>for</span> <span class=n>thread</span> <span class=ow>in</span> <span class=n>threads</span><span class=p>:</span>
<span class=n>thread</span><span class=o>.</span><span class=n>join</span><span class=p>()</span>
<span class=n>histogram</span> <span class=o>=</span> <span class=n>collections</span><span class=o>.</span><span class=n>Counter</span><span class=p>(</span><span class=n>SOCKET_PAIRS</span><span class=p>)</span>
<span class=k>for</span> <span class=p>(</span><span class=n>ip_</span><span class=p>,</span> <span class=n>port</span><span class=p>),</span> <span class=n>count</span> <span class=ow>in</span> <span class=n>histogram</span><span class=o>.</span><span class=n>most_common</span><span class=p>(</span><span class=nb>len</span><span class=p>(</span><span class=n>histogram</span><span class=p>)):</span>
<span class=nb>print</span><span class=p>(</span><span class=sa>f</span><span class=s2>"</span><span class=si>{</span><span class=n>ip_</span><span class=si>}</span><span class=s2>:</span><span class=si>{</span><span class=n>port</span><span class=si>}</span><span class=s2> -> </span><span class=si>{</span><span class=n>count</span><span class=si>}</span><span class=s2>"</span><span class=p>)</span>
</code></pre></div>
<p>shows that only 5 sockets were used to service all 256 requests</p>
<div class=highlight><pre><span></span><code><span class=mf>4</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>0</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>...</span>
<span class=mf>255</span> <span class=n>Status</span> <span class=n>Code</span><span class=p>:</span> <span class=mf>200</span>
<span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51625</span> <span class=o>-></span> <span class=mf>52</span>
<span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51624</span> <span class=o>-></span> <span class=mf>52</span>
<span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51621</span> <span class=o>-></span> <span class=mf>51</span>
<span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51623</span> <span class=o>-></span> <span class=mf>51</span>
<span class=mf>192.168.7.31</span><span class=p>:</span><span class=mf>51622</span> <span class=o>-></span> <span class=mf>50</span>
</code></pre></div><ol class=simple-footnotes><li id=sf-threadsafe-connection-pool-1>Version
<code>2.23.0</code>, running Python <code>3.8.2</code> on macOS 10.15.4 as of this
writing <a href=#sf-threadsafe-connection-pool-1-back class=simple-footnote-back>↩</a></li><li id=sf-threadsafe-connection-pool-2>I'd love to know more but was more focused
on getting a working multithreaded connection pool. <a href=#sf-threadsafe-connection-pool-2-back class=simple-footnote-back>↩</a></li></ol>Decoding HTTP/2 and gRPC2019-08-31T00:00:00-07:002019-08-31T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2019-08-31:/2019/08/http2-note.html<p>In order to learn a bit more about how both the TCP and HTTP/2 protocols work,
I recently created the <code>tcp-h2-describe</code> <a href="https://pypi.org/project/tcp-h2-describe/0.1.0/">reverse proxy</a> in Python. I was
excited about some of the insights I was able to glean from the process, in
particular a full <a href="https://github.com/dhermes/tcp-h2-describe/blob/0.1.0/EXAMPLE-gRPC.md">example</a> tracing a connection …</p><p>In order to learn a bit more about how both the TCP and HTTP/2 protocols work,
I recently created the <code>tcp-h2-describe</code> <a href="https://pypi.org/project/tcp-h2-describe/0.1.0/">reverse proxy</a> in Python. I was
excited about some of the insights I was able to glean from the process, in
particular a full <a href="https://github.com/dhermes/tcp-h2-describe/blob/0.1.0/EXAMPLE-gRPC.md">example</a> tracing a connection between a gRPC client and
server over HTTP/2.</p>
<p>When a serialized <a href="https://developers.google.com/protocol-buffers/docs/proto3">protobuf</a> comes across the wire as an HTTP/2
<a href="https://http2.github.io/http2-spec/#DATA">DATA frame</a>, the <code>tcp-h2-describe</code> proxy is able to give a faithful
description of the frame:</p>
<div class=highlight><pre><span></span><code><span class=p>...</span>
<span class=o>----------------------------------------</span>
<span class=n>Frame</span> <span class=n>Length</span> <span class=o>=</span> <span class=mi>21</span> <span class=p>(</span><span class=mi>00</span> <span class=mi>00</span> <span class=mi>15</span><span class=p>)</span>
<span class=n>Frame</span> <span class=n>Type</span> <span class=o>=</span> <span class=n>DATA</span> <span class=p>(</span><span class=mi>00</span><span class=p>)</span>
<span class=n>Flags</span> <span class=o>=</span> <span class=n>END_STREAM</span><span class=p>:</span><span class=mi>0</span><span class=n>x1</span> <span class=p>(</span><span class=mi>01</span><span class=p>)</span>
<span class=n>Stream</span> <span class=n>Identifier</span> <span class=o>=</span> <span class=mi>3</span> <span class=p>(</span><span class=mi>00</span> <span class=mi>00</span> <span class=mi>00</span> <span class=mi>03</span><span class=p>)</span>
<span class=n>gRPC</span> <span class=n>Compressed</span> <span class=n>Flag</span> <span class=o>=</span> <span class=mi>0</span> <span class=p>(</span><span class=mi>00</span><span class=p>)</span>
<span class=n>Protobuf</span> <span class=n>Length</span> <span class=o>=</span> <span class=mi>16</span> <span class=p>(</span><span class=mi>00</span> <span class=mi>00</span> <span class=mi>00</span> <span class=mi>10</span><span class=p>)</span>
<span class=n>Protobuf</span> <span class=n>Message</span> <span class=p>(</span><span class=n>users</span><span class=p>.</span><span class=n>v1</span><span class=p>.</span><span class=n>User</span><span class=p>)</span> <span class=o>=</span>
<span class=n>first_name</span><span class=p>:</span> <span class=s>"Alice"</span>
<span class=n>last_name</span><span class=p>:</span> <span class=s>"Redmond"</span>
<span class=n>Hexdump</span> <span class=p>(</span><span class=n>Protobuf</span> <span class=n>Message</span><span class=p>)</span> <span class=o>=</span>
<span class=mi>0</span><span class=n>a</span> <span class=mi>05</span> <span class=mi>41</span> <span class=mi>6</span><span class=n>c</span> <span class=mi>69</span> <span class=mi>63</span> <span class=mi>65</span> <span class=mi>12</span> <span class=mi>07</span> <span class=mi>52</span> <span class=mi>65</span> <span class=mi>64</span> <span class=mi>6</span><span class=n>d</span> <span class=mi>6</span><span class=n>f</span> <span class=mi>6</span><span class=n>e</span> <span class=mi>64</span>
<span class=o>----------------------------------------</span>
<span class=p>...</span>
</code></pre></div>
<p>In addition to decoding the data frame and providing a "pretty" description of
the deserialized <code>users.v1.User</code> coming across the wire, this also preserves
the raw bytes being sent as part of the larger TCP packet data. For example
in <code>... 6c 69 63 ...</code> the <code>69</code> (<code>0x69</code> in hexadecimal is <code>105</code> in decimal)
corresponds to the ASCII encoding of the <code>i</code> in Alice.</p>
<h3 id=why>Why?</h3>
<p>When I excitedly told my <a href="https://twitter.com/eugenemarinelli">CTO</a> Eugene "look what I built", he quickly said
"is this like <a href="https://www.wireshark.org/">Wireshark</a>?" and he hit the nail on the head. So why did I
build something <strong>much less</strong> capable than Wireshark? Well the first answer to
that question is something like "Oops".</p>
<p>It gets even better: I originally went down the path of implementing this
myself because of a silly <a href="https://twitter.com/bossylobster/status/1165164209346207745">mistake</a>. I was working on a Kubernetes service
running a gRPC server (more on that in a moment) and failed to get
off-the-shelf reverse proxies working. I tried seven different (<a href="https://github.com/google/tcpproxy">e.g.</a>)
existing proxies of varying quality (some were just in GitHub gists) but
all of them failed to actually do anything at all within the container. The
problem: I kept binding the proxy to loopback IP (i.e. <code>localhost</code> or
<code>127.0.0.1</code>) rather than the broadcast IP (<code>0.0.0.0</code>).</p>
<p>In the end though I'm better for not having been "able" to use off-the-shelf
reverse proxies because I got to learn more about the guts of TCP (which I
use all the time) and HTTP/2 (which is new to me).</p>
<h3 id=where>Where?</h3>
<p>As for where this code is running, I mentioned I'd say a bit more about the
Kubernetes service running a gRPC server. I'm currently doing some
discovery<sup id=sf-http2-note-1-back><a href=#sf-http2-note-1 class=simple-footnote title="Many thanks to Alex Fish for being my sounding board during this process">1</a></sup> on gRPC patterns; I'm trying to understand if gRPC can work
for me and possibly my team or other groups at Blend.</p>
<p>Within our infrastructure, I had a Kubernetes pod handling raw TCP traffic on
a port of my choosing. Unfortunately the AWS ELB<sup id=sf-http2-note-2-back><a href=#sf-http2-note-2 class=simple-footnote title="To my former Google Cloud colleagues, yes I use AWS every day">2</a></sup> uses the
<a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html">proxy protocol</a> to add a prefix to the packet data from the first TCP
segment. This prefix gives information about the proxied IP for raw TCP
connections that may not be able to convey<sup id=sf-http2-note-3-back><a href=#sf-http2-note-3 class=simple-footnote title="This is in contrast to HTTP, where the X-Forwarded-For header is commonly used to indicate a proxy">3</a></sup>
such information, e.g.</p>
<div class=highlight><pre><span></span><code>PROXY TCP4 198.51.100.22 203.0.113.7 35646 80
</code></pre></div>
<p>Due to my loopback IP vs. broadcast IP mixup, I wasn't able to get our
<code>proxyprotocol</code> <a href="https://godoc.org/github.com/blend/go-sdk/proxyprotocol">package</a> working with the <code>google/tcpproxy</code> <a href="https://github.com/google/tcpproxy">package</a>.
Without a reverse proxy that could strip the prefix from the TCP packet
data, my gRPC server could not handle the request. So I set off to understand
TCP a little bit better and write my own reverse proxy that could strip the
proxy protocol prefix.</p>
<h3 id=what>What?</h3>
<p>The <code>tcp-h2-describe</code> reverse proxy directs HTTP/2 traffic<sup id=sf-http2-note-4-back><a href=#sf-http2-note-4 class=simple-footnote title="For now, this only supports unencrypted traffic, though it is possible to use TLS in such a proxy if the proxy is able to share the certs of the server being proxied">4</a></sup>
from a client to a server:</p>
<div class=highlight><pre><span></span><code>$ tcp-h2-describe --server-host website.invalid --server-port <span class=m>80</span>
Starting tcp-h2-describe proxy server on port <span class=m>24909</span>
Proxying server located at website.invalid:80
...
</code></pre></div>
<p>Once a request is sent through, the TCP packet data is parsed as a series of
HTTP/2 <a href="https://http2.github.io/http2-spec/#FramingLayer">frames</a> and each byte in the data is accounted for.</p>
<p>In the HTTP <a href="https://github.com/dhermes/tcp-h2-describe/blob/0.1.0/EXAMPLE-HTTP.md">example</a> provided in the library's documentation, proxied
traffic is sent to a locally running HTTP/2 server. The packet data from the
first TCP segment sent by the client contains 84 bytes:</p>
<div class=highlight><pre><span></span><code><span class=mf>00000000</span> <span class=mf>50</span> <span class=mf>52</span> <span class=mf>49</span> <span class=mf>20</span> <span class=mf>2</span><span class=n>a</span> <span class=mf>20</span> <span class=mf>48</span> <span class=mf>54</span> <span class=mf>54</span> <span class=mf>50</span> <span class=mf>2</span><span class=n>f</span> <span class=mf>32</span> <span class=mf>2</span><span class=n>e</span> <span class=mf>30</span> <span class=mf>0</span><span class=n>d</span> <span class=mf>0</span><span class=n>a</span> <span class=err>|</span><span class=n>PRI</span> <span class=o>*</span> <span class=n>HTTP</span><span class=o>/</span><span class=mf>2.0..</span><span class=err>|</span>
<span class=mf>00000010</span> <span class=mf>0</span><span class=n>d</span> <span class=mf>0</span><span class=n>a</span> <span class=mf>53</span> <span class=mf>4</span><span class=n>d</span> <span class=mf>0</span><span class=n>d</span> <span class=mf>0</span><span class=n>a</span> <span class=mf>0</span><span class=n>d</span> <span class=mf>0</span><span class=n>a</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>24</span> <span class=mf>04</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=err>|</span><span class=mf>..</span><span class=n>SM</span><span class=mf>......</span><span class=err>$</span><span class=mf>.....</span><span class=err>|</span>
<span class=mf>00000020</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>01</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>10</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>02</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>01</span> <span class=mf>00</span> <span class=mf>04</span> <span class=mf>00</span> <span class=err>|</span><span class=mf>................</span><span class=err>|</span>
<span class=mf>00000030</span> <span class=mf>00</span> <span class=n>ff</span> <span class=n>ff</span> <span class=mf>00</span> <span class=mf>05</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>40</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>03</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>64</span> <span class=mf>00</span> <span class=err>|</span><span class=mf>.......</span><span class=err>@</span><span class=mf>......</span><span class=n>d</span><span class=mf>.</span><span class=err>|</span>
<span class=mf>00000040</span> <span class=mf>06</span> <span class=mf>00</span> <span class=mf>01</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>06</span> <span class=mf>04</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>02</span> <span class=err>|</span><span class=mf>................</span><span class=err>|</span>
<span class=mf>00000050</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=mf>00</span> <span class=err>|</span><span class=mf>....</span><span class=err>|</span>
<span class=mf>00000054</span>
</code></pre></div>
<p>We can see most of these bytes are not printable characters, however
<code>tcp-h2-describe</code> breaks this TCP packet data down and explains how every
single byte is used:</p>
<div class=highlight><pre><span></span><code><span class=p>...</span>
<span class=o>============================================================</span>
<span class=n>client</span><span class=p>(</span><span class=mf>127.0.0.1</span><span class=o>:</span><span class=mi>59600</span><span class=p>)</span><span class=o>-></span><span class=n>proxy</span><span class=o>-></span><span class=n>server</span><span class=p>(</span><span class=n>localhost</span><span class=o>:</span><span class=mi>8080</span><span class=p>)</span>
<span class=n>Client</span> <span class=n>Connection</span> <span class=n>Preface</span> <span class=o>=</span> <span class=n>b</span><span class=s>'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n'</span>
<span class=n>Hexdump</span> <span class=p>(</span><span class=n>Client</span> <span class=n>Connection</span> <span class=n>Preface</span><span class=p>)</span> <span class=o>=</span>
<span class=mi>50</span> <span class=mi>52</span> <span class=mi>49</span> <span class=mi>20</span> <span class=mi>2</span><span class=n>a</span> <span class=mi>20</span> <span class=mi>48</span> <span class=mi>54</span> <span class=mi>54</span> <span class=mi>50</span> <span class=mf>2f</span> <span class=mi>32</span> <span class=mi>2</span><span class=n>e</span> <span class=mi>30</span> <span class=mi>0</span><span class=n>d</span> <span class=mi>0</span><span class=n>a</span>
<span class=mi>0</span><span class=n>d</span> <span class=mi>0</span><span class=n>a</span> <span class=mi>53</span> <span class=mi>4</span><span class=n>d</span> <span class=mi>0</span><span class=n>d</span> <span class=mi>0</span><span class=n>a</span> <span class=mi>0</span><span class=n>d</span> <span class=mi>0</span><span class=n>a</span>
<span class=o>----------------------------------------</span>
<span class=n>Frame</span> <span class=nf>Length</span> <span class=o>=</span> <span class=mi>36</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>00</span> <span class=mi>24</span><span class=p>)</span>
<span class=n>Frame</span> <span class=kr>Type</span> <span class=o>=</span> <span class=n>SETTINGS</span> <span class=p>(</span><span class=mo>04</span><span class=p>)</span>
<span class=n>Flags</span> <span class=o>=</span> <span class=n>UNSET</span> <span class=p>(</span><span class=mo>00</span><span class=p>)</span>
<span class=n>Stream</span> <span class=n>Identifier</span> <span class=o>=</span> <span class=mi>0</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mo>00</span><span class=p>)</span>
<span class=n>Settings</span> <span class=o>=</span>
<span class=n>SETTINGS_HEADER_TABLE_SIZE</span><span class=o>:</span><span class=mh>0x1</span> <span class=o>-></span> <span class=mi>4096</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>01</span> <span class=o>|</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mi>10</span> <span class=mo>00</span><span class=p>)</span>
<span class=n>SETTINGS_ENABLE_PUSH</span><span class=o>:</span><span class=mh>0x2</span> <span class=o>-></span> <span class=mi>1</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>02</span> <span class=o>|</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mo>01</span><span class=p>)</span>
<span class=n>SETTINGS_INITIAL_WINDOW_SIZE</span><span class=o>:</span><span class=mh>0x4</span> <span class=o>-></span> <span class=mi>65535</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>04</span> <span class=o>|</span> <span class=mo>00</span> <span class=mo>00</span> <span class=n>ff</span> <span class=n>ff</span><span class=p>)</span>
<span class=n>SETTINGS_MAX_FRAME_SIZE</span><span class=o>:</span><span class=mh>0x5</span> <span class=o>-></span> <span class=mi>16384</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>05</span> <span class=o>|</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mi>40</span> <span class=mo>00</span><span class=p>)</span>
<span class=n>SETTINGS_MAX_CONCURRENT_STREAMS</span><span class=o>:</span><span class=mh>0x3</span> <span class=o>-></span> <span class=mi>100</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>03</span> <span class=o>|</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mi>64</span><span class=p>)</span>
<span class=n>SETTINGS_MAX_HEADER_LIST_SIZE</span><span class=o>:</span><span class=mh>0x6</span> <span class=o>-></span> <span class=mi>65536</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>06</span> <span class=o>|</span> <span class=mo>00</span> <span class=mo>01</span> <span class=mo>00</span> <span class=mo>00</span><span class=p>)</span>
<span class=o>----------------------------------------</span>
<span class=n>Frame</span> <span class=nf>Length</span> <span class=o>=</span> <span class=mi>6</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>00</span> <span class=mo>06</span><span class=p>)</span>
<span class=n>Frame</span> <span class=kr>Type</span> <span class=o>=</span> <span class=n>SETTINGS</span> <span class=p>(</span><span class=mo>04</span><span class=p>)</span>
<span class=n>Flags</span> <span class=o>=</span> <span class=n>UNSET</span> <span class=p>(</span><span class=mo>00</span><span class=p>)</span>
<span class=n>Stream</span> <span class=n>Identifier</span> <span class=o>=</span> <span class=mi>0</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mo>00</span><span class=p>)</span>
<span class=n>Settings</span> <span class=o>=</span>
<span class=n>SETTINGS_ENABLE_PUSH</span><span class=o>:</span><span class=mh>0x2</span> <span class=o>-></span> <span class=mi>0</span> <span class=p>(</span><span class=mo>00</span> <span class=mo>02</span> <span class=o>|</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mo>00</span> <span class=mo>00</span><span class=p>)</span>
<span class=o>----------------------------------------</span>
<span class=p>...</span>
</code></pre></div>
<h3 id=go-deeper>Go Deeper?</h3>
<p>I was eventually able to handle the proxy protocol line that gets prepended by
the AWS ELB (see an <a href="https://github.com/dhermes/tcp-h2-describe/blob/0.1.0/EXAMPLE-PROXY-PROTOCOL.md">example</a>). In order to handle proxy protocol and
regular TCP connections the same way I had to <a href="https://github.com/dhermes/tcp-h2-describe/blob/0.1.0/src/tcp_h2_describe/_proxy_protocol.py#L166">use</a> <code>MSG_PEEK</code> to avoid
reading bytes I didn't want to use while handling the proxy protocol
prefix<sup id=sf-http2-note-5-back><a href=#sf-http2-note-5 class=simple-footnote title="Hat tip to Will Charczuk for the proxyprotocol package, which I used as a basis">5</a></sup>.</p>
<p>I did read a bit about going <a href="https://jvns.ca/blog/2014/08/12/what-happens-if-you-write-a-tcp-stack-in-python/">deep enough</a> in the stack to actually
construct a TCP packet, but luckily I was able to avoid having to deal with
<a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure">TCP segment structure</a></p>
<div style="text-align: center;">
<p><img alt="TCP Packet" src="/images/tcp-packet.png"></p>
</div>
<p>and was just able to focus on the TCP package data. This is because the
<code>socket</code> <a href="https://docs.python.org/3/library/socket.html">module</a> in Python's standard library provides a very nice
interface intended to emulate the</p>
<blockquote>
<p>Unix system call and library interface for sockets</p>
</blockquote>
<p>In particular it allows focusing on the data within a TCP packet via
<code>recv()</code> and <code>send()</code>.</p>
<p>Once I got a handle on this process I was able to implement a reverse proxy
that opens <strong>two</strong> sockets: one for the client making a TCP request to the
proxy and one for the server being proxied. It simultaneously calls <code>recv()</code>
and <code>send()</code> on each socket, making sure to act as a trampoline that sends data
between the client and the server. For example, any data returned from a
<code>recv()</code> and server socket immediately gets passed to <code>send()</code> on the client
socket.</p>
<p>Since the data is "in the middle" while the proxy hands it from one socket
to another, the proxy can decode the series of HTTP/2 frames contained in
the data and print the findings to the console.</p><ol class=simple-footnotes><li id=sf-http2-note-1>Many thanks to <a href="https://github.com/alexfish8">Alex Fish</a> for being my sounding board during
this process <a href=#sf-http2-note-1-back class=simple-footnote-back>↩</a></li><li id=sf-http2-note-2>To my
former Google Cloud colleagues, yes I use AWS every day <a href=#sf-http2-note-2-back class=simple-footnote-back>↩</a></li><li id=sf-http2-note-3>This is in contrast to HTTP,
where the <code>X-Forwarded-For</code> header is commonly used to indicate a proxy <a href=#sf-http2-note-3-back class=simple-footnote-back>↩</a></li><li id=sf-http2-note-4>For now, this
only supports unencrypted traffic, though it is possible to use TLS in such a
proxy if the proxy is able to share the certs of the server being proxied <a href=#sf-http2-note-4-back class=simple-footnote-back>↩</a></li><li id=sf-http2-note-5>Hat tip to <a href="https://github.com/wcharczuk">Will Charczuk</a> for the <code>proxyprotocol</code>
<a href="https://godoc.org/github.com/blend/go-sdk/proxyprotocol">package</a>, which I used as a basis <a href=#sf-http2-note-5-back class=simple-footnote-back>↩</a></li></ol>Type Guards for Union Types in TypeScript2019-06-09T00:00:00-07:002019-06-09T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2019-06-09:/2019/06/type-guards-for-union-types.html<p>In my day job at Blend, I write a lot of TypeScript<sup id=sf-type-guards-for-union-types-1-back><a href=#sf-type-guards-for-union-types-1 class=simple-footnote title="This may surprise many of my colleagues from the Python world">1</a></sup>. One great feature of
TypeScript is the ability to specify an enum with a finite set of values
as a <a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types">union type</a>:</p>
<div class=highlight><pre><span></span><code><span class=kd>type</span> <span class=nx>Coordinate</span> <span class=o>=</span> <span class=s1>'x'</span> <span class=o>|</span> <span class=s1>'y'</span>
</code></pre></div>
<p>which then gives compile time checking for values of this type …</p><p>In my day job at Blend, I write a lot of TypeScript<sup id=sf-type-guards-for-union-types-1-back><a href=#sf-type-guards-for-union-types-1 class=simple-footnote title="This may surprise many of my colleagues from the Python world">1</a></sup>. One great feature of
TypeScript is the ability to specify an enum with a finite set of values
as a <a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types">union type</a>:</p>
<div class=highlight><pre><span></span><code><span class=kd>type</span> <span class=nx>Coordinate</span> <span class=o>=</span> <span class=s1>'x'</span> <span class=o>|</span> <span class=s1>'y'</span>
</code></pre></div>
<p>which then gives compile time checking for values of this type</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>coordinate</span>: <span class=kt>Coordinate</span> <span class=o>=</span> <span class=s1>'x'</span>
<span class=c1>// This will not compile: const coordinate: Coordinate = 'donut'</span>
</code></pre></div>
<h3>Contents</h3>
<ul>
<li><a href=#whats-missing>What's Missing</a></li>
<li><a href=#what-can-go-wrong>What Can Go Wrong</a></li>
<li><a href=#how-can-we-fix-it>How Can We Fix It</a></li>
<li><a href=#but-what-about>But What About ...</a></li>
<li><a href=#related-approaches>Related Approaches</a></li>
</ul>
<h3 id=whats-missing>What's Missing</h3>
<p>Unfortunately, there is no utility built into the language that will provide
an array of the values in the union type. I.e. for our <code>Coordinate</code> type, we
often want:</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>COORDINATES</span>: <span class=kt>Coordinate</span><span class=p>[]</span> <span class=o>=</span> <span class=p>[</span><span class=s1>'x'</span><span class=p>,</span> <span class=s1>'y'</span><span class=p>]</span>
<span class=c1>// Or even better, make it immutable: Object.freeze(['x', 'y'])</span>
</code></pre></div>
<p>Such a <code>COORDINATES</code> array has many uses. It's common to use such an array
to write a <a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types">type guard</a></p>
<div class=highlight><pre><span></span><code><span class=kd>function</span> <span class=nx>isCoordinate</span><span class=p>(</span><span class=nx>value</span>: <span class=kt>string</span><span class=p>)</span><span class=o>:</span> <span class=nx>value</span> <span class=nx>is</span> <span class=nx>Coordinate</span> <span class=p>{</span>
<span class=k>return</span> <span class=nx>COORDINATES</span><span class=p>.</span><span class=nx>includes</span><span class=p>(</span><span class=nx>value</span><span class=p>)</span>
<span class=p>}</span>
</code></pre></div>
<p>or to specify a <a href="https://github.com/hapijs/joi"><code>Joi</code> schema</a> for an external facing API:</p>
<div class=highlight><pre><span></span><code><span class=k>import</span> <span class=o>*</span> <span class=kr>as</span> <span class=nx>Joi</span> <span class=k>from</span> <span class=s1>'@hapi/joi'</span>
<span class=kd>const</span> <span class=nx>REPLACE_VALUE</span>: <span class=kt>Joi.ObjectSchema</span> <span class=o>=</span> <span class=nx>Joi</span><span class=p>.</span><span class=nx>object</span><span class=p>({</span>
<span class=nx>id</span>: <span class=kt>Joi.string</span><span class=p>().</span><span class=nx>guid</span><span class=p>().</span><span class=nx>required</span><span class=p>(),</span>
<span class=nx>coordinate</span>: <span class=kt>Joi.string</span><span class=p>().</span><span class=nx>valid</span><span class=p>(</span><span class=nx>COORDINATES</span><span class=p>).</span><span class=nx>required</span><span class=p>(),</span>
<span class=nx>value</span>: <span class=kt>Joi.number</span><span class=p>().</span><span class=nx>required</span><span class=p>(),</span>
<span class=p>})</span>
</code></pre></div>
<h3 id=what-can-go-wrong>What Can Go Wrong</h3>
<p>It's easy enough to just hardcode <code>COORDINATES</code> to exactly agree with your
<code>Coordinate</code> union type and feel happy that it's a comprehensive coverage of
the values. Even better, since <code>COORDINATES</code> has the type <code>Coordinate[]</code>, you
have a guarantee<sup id=sf-type-guards-for-union-types-2-back><a href=#sf-type-guards-for-union-types-2 class=simple-footnote title="Provided you don't use any as Coordinate[] type assertion funny business">2</a></sup> from the <code>tsc</code>
compiler that you won't have any invalid values.</p>
<p>However, let's say one day your codebase decides to expand from 2D into 3D:</p>
<div class=highlight><pre><span></span><code><span class=kd>type</span> <span class=nx>Coordinate</span> <span class=o>=</span> <span class=s1>'x'</span> <span class=o>|</span> <span class=s1>'y'</span> <span class=o>|</span> <span class=s1>'z'</span>
</code></pre></div>
<p>None of the rest of your code will break, but it <strong>should have</strong>! Your
<code>COORDINATES</code> covering set is no longer a covering set, but both <code>x</code> and <code>y</code>
are valid. Calling <code>isCoordinate('z')</code> will return <code>false</code> (which is a lie)
and your <code>REPLACE_VALUE</code> schema will reject calls to your API that want to
replace the <code>z</code> value.</p>
<h3 id=how-can-we-fix-it>How Can We Fix It</h3>
<p>By hardcoding <code>COORDINATES</code> we've accidentally made our codebase brittle. The
<code>['x', 'y']</code> <a href="https://en.wikipedia.org/wiki/Literal_(computer_programming)">literal</a> encodes an <strong>assumption</strong> about our code that is not
checked anywhere at all. Also, the <code>tsc</code> compiler has no hope in helping us
because <code>COORDINATES</code> is a <strong>value</strong>, not a <strong>type</strong>, so <code>tsc</code> isn't able to
make any extra assertions to act as a guard rail.</p>
<p>Unit tests to the rescue! We can write a single unit test (<a href="https://github.com/avajs/ava">with <code>ava</code></a>)
that is guaranteed to fail if either the <code>Coordinate</code> union type or the
<code>COORDINATES</code> value is changed:</p>
<div class=highlight><pre><span></span><code><span class=k>import</span> <span class=nx>test</span> <span class=k>from</span> <span class=s1>'ava'</span>
<span class=nx>test</span><span class=p>(</span><span class=s1>'COORDINATES covers the Coordinate union type'</span><span class=p>,</span> <span class=nx>t</span> <span class=o>=></span> <span class=p>{</span>
<span class=kd>const</span> <span class=nx>asKeys</span>: <span class=kt>Record</span><span class=o><</span><span class=nx>Coordinate</span><span class=p>,</span> <span class=kt>number</span><span class=o>></span> <span class=o>=</span> <span class=p>{</span> <span class=nx>x</span>: <span class=kt>0</span><span class=p>,</span> <span class=nx>y</span>: <span class=kt>0</span> <span class=p>}</span>
<span class=kd>const</span> <span class=nx>expectedKeys</span> <span class=o>=</span> <span class=nb>Object</span><span class=p>.</span><span class=nx>keys</span><span class=p>(</span><span class=nx>asKeys</span><span class=p>).</span><span class=nx>sort</span><span class=p>()</span>
<span class=c1>// NOTE: Sort `COORDINATES` without mutating it.</span>
<span class=kd>const</span> <span class=nx>actualKeys</span> <span class=o>=</span> <span class=nx>COORDINATES</span><span class=p>.</span><span class=nx>concat</span><span class=p>().</span><span class=nx>sort</span><span class=p>()</span>
<span class=nx>t</span><span class=p>.</span><span class=nx>deepEqual</span><span class=p>(</span><span class=nx>expectedKeys</span><span class=p>,</span> <span class=nx>actualKeys</span><span class=p>)</span>
<span class=p>})</span>
</code></pre></div>
<p>Using the <a href="https://stackoverflow.com/a/51937036/1068170"><code>Record<></code> type</a> allows the <strong>compiler</strong> to tell us if any
members of the <code>Coordinate</code> are absent keys in <code>asKeys</code>. Then at <strong>runtime</strong>
we use <code>Object.keys()</code> to convert those (already compiler checked) keys into
a <strong>value</strong> <code>expectedKeys</code>. Then we can ensure that <code>expectedKeys</code> is verified
against <code>COORDINATES</code>.</p>
<h3 id=but-what-about>But What About ...</h3>
<p>The snippet in the unit test absolutely provides a template for doing this
inline (i.e. without the support of a unit test):</p>
<div class=highlight><pre><span></span><code><span class=kd>type</span> <span class=nx>Coordinate</span> <span class=o>=</span> <span class=s1>'x'</span> <span class=o>|</span> <span class=s1>'y'</span>
<span class=kd>const</span> <span class=nx>asKeys</span>: <span class=kt>Record</span><span class=o><</span><span class=nx>Coordinate</span><span class=p>,</span> <span class=kt>number</span><span class=o>></span> <span class=o>=</span> <span class=p>{</span> <span class=nx>x</span>: <span class=kt>0</span><span class=p>,</span> <span class=nx>y</span>: <span class=kt>0</span> <span class=p>}</span>
<span class=kd>const</span> <span class=nx>COORDINATES</span>: <span class=kt>Coordinate</span><span class=p>[]</span> <span class=o>=</span> <span class=nb>Object</span><span class=p>.</span><span class=nx>keys</span><span class=p>(</span><span class=nx>asKeys</span><span class=p>)</span>
</code></pre></div>
<p>however, this snippet of code will fail due to the return type of
<code>Object.keys()</code>:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>tsc snippet.ts
<span class=go>snippet.ts:6:7 - error TS2322: Type 'string[]' is not assignable to type 'Coordinate[]'.</span>
<span class=go> Type 'string' is not assignable to type 'Coordinate'.</span>
<span class=go>6 const COORDINATES: Coordinate[] = Object.keys(asKeys)</span>
<span class=go> ~~~~~~~~~~~</span>
<span class=go>Found 1 error.</span>
</code></pre></div>
<p>So in order to use it, you'd need to resort back to a type assertion (and IMO
type assertions should be avoided at all costs).</p>
<p>Additionally, though declaring <code>asKeys</code> only takes up one line, it's a bit
of an eyesore in <strong>source</strong> code (vs. <strong>test</strong> code). As the number of allowed
values in a given union type goes up, declaring <code>asKeys</code> inline will look even
worse.</p>
<h3 id=related-approaches>Related Approaches</h3>
<p>I've also had cases where I had a use in my code for a mapping identical to what
was provided by <code>Record<></code>. It's equally fine to define that mapping
directly and derive the <code>Coordinate</code> union type from it via the
<a href="https://mariusschulz.com/blog/typescript-2-1-keyof-and-lookup-types"><code>keyof</code> keyword</a></p>
<div class=highlight><pre><span></span><code><span class=kd>interface</span> <span class=nx>Point</span> <span class=p>{</span>
<span class=nx>x</span>: <span class=kt>number</span>
<span class=nx>y</span>: <span class=kt>number</span>
<span class=p>}</span>
<span class=kd>type</span> <span class=nx>Coordinate</span> <span class=o>=</span> <span class=nx>keyof</span> <span class=nx>Point</span>
</code></pre></div>
<p>Then the unit test will change ever so slightly<sup id=sf-type-guards-for-union-types-3-back><a href=#sf-type-guards-for-union-types-3 class=simple-footnote title="In cases where some of the keys are optional, a Required<Point> must be used for the type of asKeys. The Required<> type was added in TypeScript 2.8.)">3</a></sup></p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>asKeys</span>: <span class=kt>Point</span> <span class=o>=</span> <span class=p>{</span> <span class=nx>x</span>: <span class=kt>0</span><span class=p>,</span> <span class=nx>y</span>: <span class=kt>0</span> <span class=p>}</span>
</code></pre></div>
<p>In codebases where "no magic constants" is a rule<sup id=sf-type-guards-for-union-types-4-back><a href=#sf-type-guards-for-union-types-4 class=simple-footnote title="I.e. typing 'x' or 'y' would not be allowed">4</a></sup>, a convenience <code>enum</code> can
be provided to give named variables for each value in the <code>Coordinate</code> type:</p>
<div class=highlight><pre><span></span><code><span class=kd>enum</span> <span class=nx>CoordinateNames</span> <span class=p>{</span>
<span class=nx>x</span> <span class=o>=</span> <span class=s1>'x'</span><span class=p>,</span>
<span class=nx>y</span> <span class=o>=</span> <span class=s1>'y'</span><span class=p>,</span>
<span class=p>}</span>
<span class=kd>type</span> <span class=nx>Coordinate</span> <span class=o>=</span> <span class=nx>keyof</span> <span class=k>typeof</span> <span class=nx>CoordinateNames</span>
</code></pre></div>
<p>Since a <a href="https://www.typescriptlang.org/docs/handbook/enums.html">TypeScript <code>enum</code></a> is really just an <code>object</code>, we can use it
directly in our unit test without having to form the stand-in <code>asKeys</code> value</p>
<div class=highlight><pre><span></span><code><span class=kd>const</span> <span class=nx>expectedKeys</span> <span class=o>=</span> <span class=nb>Object</span><span class=p>.</span><span class=nx>keys</span><span class=p>(</span><span class=nx>CoordinateNames</span><span class=p>).</span><span class=nx>sort</span><span class=p>()</span>
</code></pre></div><ol class=simple-footnotes><li id=sf-type-guards-for-union-types-1>This may surprise
many of my colleagues from the Python world <a href=#sf-type-guards-for-union-types-1-back class=simple-footnote-back>↩</a></li><li id=sf-type-guards-for-union-types-2>Provided you don't use any
<code>as Coordinate[]</code> <a href="https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions">type assertion</a> funny business <a href=#sf-type-guards-for-union-types-2-back class=simple-footnote-back>↩</a></li><li id=sf-type-guards-for-union-types-3>In cases where some of the
keys are optional, a <code>Required<Point></code> must be used for the type of <code>asKeys</code>.
The <code>Required<></code> type was <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html">added</a> in TypeScript 2.8.) <a href=#sf-type-guards-for-union-types-3-back class=simple-footnote-back>↩</a></li><li id=sf-type-guards-for-union-types-4>I.e. typing <code>'x'</code> or
<code>'y'</code> would not be allowed <a href=#sf-type-guards-for-union-types-4-back class=simple-footnote-back>↩</a></li></ol>Attack of Ruby Stack Traces2019-05-27T00:00:00-07:002019-05-27T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2019-05-27:/2019/05/ruby-stack-traces.html<p>First, let me say I'm not posting this to shame any company or language
community. Getting to the scale Twitter reached in a short amount of time
can quickly make past engineering decisions look foolish in hindsight. But
almost always they are decisions made in good faith with the current …</p><p>First, let me say I'm not posting this to shame any company or language
community. Getting to the scale Twitter reached in a short amount of time
can quickly make past engineering decisions look foolish in hindsight. But
almost always they are decisions made in good faith with the current
information.</p>
<p>Over the past 6 months, I've been trying my hardest to find an old talk I had
watched about a bug at Twitter that was responsible for the fail whale. I
<strong>could not</strong> find the talk for all I tried. When trying to find the talk, I
was searching for "memory leak" caused by "Ruby stack traces".</p>
<div style="text-align: center;">
<p><img alt="Twitter Fail Whale" src="/images/fail-whale.png"></p>
</div>
<p>I couldn't find the talk for several reasons</p>
<ul>
<li>I thought the speaker was <a href="https://twitter.com/garybernhardt">Gary Bernhardt</a><sup id=sf-ruby-stack-traces-1-back><a href=#sf-ruby-stack-traces-1 class=simple-footnote title="His talk The Birth & Death of JavaScript is so good">1</a></sup> but it was actually
<a href="https://twitter.com/bcantrill">Bryan Cantrill</a></li>
<li>I was searching for "memory leak" but the issue was actually caused by
excessive use of compute resources</li>
<li>The comment was just a small footnote in a much longer talk about
<a href="https://www.youtube.com/watch?v=LjFM8vw3pbU">The Summer of Rust</a></li>
</ul>
<p>When I finally found the talk, I was so excited. In order to make my future
Google searches actually turn up results I wanted to write this blog post.
Also, to make the searches a little more useful, please find the transcript
starting at the 26:30 mark<sup id=sf-ruby-stack-traces-2-back><a href=#sf-ruby-stack-traces-2 class=simple-footnote title='Edited a slight bit by removing some words such as "like"'>2</a></sup>:</p>
<blockquote>
<p>If you think Ruby's inefficient today ... Twitter was a big customer of ours
and in 2007 I went into Twitter because – I feel like I'm the internet
historian here – back in the day there was this thing called the fail
whale on Twitter. Do you remember the fail whale? OK right.</p>
<p>So Twitter would constantly keel over, you'd get like this whale that was
indicating that things were awful and it was threatening the company. People
wanted to not use Twitter as a result of this. Little did they know that
there would be lots of other reasons to not use Twitter in the future but
this is back when the actual the reliability of the thing was the biggest
problem not like you know the Pepes or whatever.</p>
<p>So we went into Twitter to try to help them understand what was going on and
using <a href="http://dtrace.org/blogs/about/"><code>dtrace</code></a> to understand where it was spending time. I remember they
were spending 460 milliseconds of compute for a request.</p>
<blockquote>
<p><strong>Bryan Cantrill</strong> "Do you mean microseconds?"</p>
<p><strong>Twitter</strong> "460 milliseconds"</p>
<p><strong>Bryan Cantrill</strong> "There's I/O. You're I/O bound."</p>
<p><strong>Twitter</strong> "No no we're not I/O bound. It's 100% compute bound."</p>
<p><strong>Bryan Cantrill</strong> "Are you sure that's right, that you're spending ... For
one request? <strong>One request</strong> would spend 460 milliseconds? Are you
sure ...?"</p>
</blockquote>
<p>But it was, it was milliseconds. Actually turns out what they were doing is
kind of interesting and it shows the peril of language choices. They were
spending all of their time in <code>bcopy()</code>, like 100% of their time in
<code>bcopy()</code>. Why are they in <code>bcopy()</code>? They're in <code>bcopy()</code> because they are
<code>bcopy()</code>-ing symbols out of their stack.</p>
<p>Why are they doing this? Because
they are deep deep deep in their Rails app and it was thought that to
actually iterate over all the elements of an array from zero to the length
the array – that's way too pedestrian, that's like repeating yourself
or whatever. That's not DRY or whatever I don't even know what the Dogma was
at the time. The "right" way to do this is to just blast through the array
until you fall off the end and get an exception thrown at you. Exactly,
you're like (brakes screeching sound) well you know it was ... anyway I don't
know what to say about it.</p>
<p>So what would happen is, it would go flying off the end of this array. It's
like a four element array and it's hitting the fifth element and of course
it's an exception and exceptions are really (should be) exceptional and when
that exception is generated what Ruby would do is like "all right I now need
to get a full stack back trace so you've got some hope in hell of figuring
out where this random exception is" because the alternative is much worse.
The alternative is like "something somewhere in there died and I got no idea
where but we're now dead" so you don't want that, right? You want to have a
stack backtrace.</p>
<p>So it would walk up whatever it was, 434 stack frames and
for each stack frame – and this is where you get to the point where
it's like Ruby could be a little bit more efficient – for each stack
frame it's looking up this symbol (and this kind of very inefficient
mechanism for looking up a symbol) it would generate this huge string buffer,
this 16K string buffer and it would: "alright time to get this ocean liner
upstairs". It would kick that up to literally the caller of this thing "oh I
got it that's fine I'm off the end of the array, no problem. I get it. But
I've done it the right way! I've done it without repeating myself or
whatever." (Facepalm)</p>
<p>It's like "oh k". So that was obviously very bad. And it highlights a bunch
of things. It highlights the cost of some of these abstractions, the runtime
cost of some of these abstractions. How difficult it is to find these things
when they misbehave that way. And how easy it is to abuse these things.</p>
</blockquote>
<p>I've really enjoyed listening to both Bryan Cantrill and Gary Bernhardt talk
about software and I highly recommend watching <strong>many</strong> of their great talks.
Also it was super cool that when I finally <a href="https://twitter.com/bossylobster/status/1129873135132659714">tweeted</a> about my search
for this old Twitter bug both Gary and Bryan interacted on Twitter!</p><ol class=simple-footnotes><li id=sf-ruby-stack-traces-1>His talk
<a href="https://www.destroyallsoftware.com/talks/the-birth-and-death-of-javascript">The Birth & Death of JavaScript</a> is so good <a href=#sf-ruby-stack-traces-1-back class=simple-footnote-back>↩</a></li><li id=sf-ruby-stack-traces-2>Edited a
slight bit by removing some words such as "like" <a href=#sf-ruby-stack-traces-2-back class=simple-footnote-back>↩</a></li></ol>Learn You a LAPACK for Great Good2018-09-13T00:00:00-07:002018-09-13T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2018-09-13:/2018/09/learn-you-a-lapack.html<p>Linear Algebra is an incredibly powerful tool. A joke among mathematicians
is that the only way we can solve a hard problem is to boil it down to
Linear Algebra<sup id=sf-learn-you-a-lapack-1-back><a href=#sf-learn-you-a-lapack-1 class=simple-footnote title="This actually happened to me. My undergraduate research project (REU) eventually boiled down to showing that a particularly special matrix had a nonzero determinant.">1</a></sup>. Harnessing the <strong>numerical</strong> power of
Linear Algebra has been done via <a href="https://en.wikipedia.org/wiki/LAPACK">LAPACK</a> for the last 40+ years.</p>
<p>In my …</p><p>Linear Algebra is an incredibly powerful tool. A joke among mathematicians
is that the only way we can solve a hard problem is to boil it down to
Linear Algebra<sup id=sf-learn-you-a-lapack-1-back><a href=#sf-learn-you-a-lapack-1 class=simple-footnote title="This actually happened to me. My undergraduate research project (REU) eventually boiled down to showing that a particularly special matrix had a nonzero determinant.">1</a></sup>. Harnessing the <strong>numerical</strong> power of
Linear Algebra has been done via <a href="https://en.wikipedia.org/wiki/LAPACK">LAPACK</a> for the last 40+ years.</p>
<p>In my first semester of graduate school, I took UC Berkeley's Math 221, i.e.
Numerical Linear Algebra. So in my second semester, I was ready to put my
new skills to use. However, when I tried to use LAPACK from C and C++ code for
an assignment, I gave up before getting anything working. I was frustrated
by my deadline, by the LAPACK <a href="http://www.netlib.org/lapack/explore-html/">documentation</a> (I didn't know where to look
or how to read what I did find), by actually forming the arguments correctly
and by getting the compiler flags right. I just gave up and turned to my trusty
friend Python; I used a combination of NumPy and the low-level
<code>scipy.linalg.lapack</code> package when necessary.</p>
<p>I wished then that there was a blog post exactly like this one. Our goal here
is to call a single LAPACK routine (<code>dgetrf</code>) from a few different contexts
to get a feel for the library structure, argument specification, reading
documentation and linking / building code.</p>
<h3>Contents</h3>
<ul>
<li><a href=#lu-factorization>LU Factorization</a></li>
<li><a href=#high-level-py>High-Level Python</a></li>
<li><a href=#finding-lapack>Finding LAPACK</a></li>
<li><a href=#low-level-py>Low-Level Python</a></li>
<li><a href=#c>C</a></li>
<li><a href=#compiling-on-os-x>Compiling on OS X</a></li>
<li><a href=#cpp>C++</a></li>
<li><a href=#conclusion>Conclusion</a></li>
</ul>
<h3 id=lu-factorization>LU Factorization</h3>
<p>As mentioned, we'll focus on the <code>dgetrf</code> method for performing
<a href="https://en.wikipedia.org/wiki/LU_decomposition">LU Factorization</a>. The names themselves can be confusing to newcomers.
Luckily the Wikipedia <a href="https://en.wikipedia.org/wiki/LAPACK">page</a> does a great job describing what is happening:</p>
<ul>
<li><code>d</code>: the matrix entries are of type <code>double</code> (i.e. a 64-bit IEEE-754
floating point number)</li>
<li><code>ge</code>: the matrix is in <strong>ge</strong>neral form, as opposed to triangular, banded,
symmetric, or many other types of matrix where information need not be
repeated</li>
<li><code>trf</code>: triangular factorization</li>
</ul>
<p>We'll focus on factoring a particular matrix <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo>=</mo><mi>L</mi><mi>U</mi></mrow><annotation encoding="application/x-tex">A = LU</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal">A</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.10903em;>LU</span></span></span></span>:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><munder><munder><mrow><mo fence=true>[</mo><mtable rowspacing=0.1600em columnalign="center center center" columnspacing=1em><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mn>4</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>4</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mrow><mo>−</mo><mn>3</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mn>0</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>4</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mrow><mo>−</mo><mn>1</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>1</mn></mstyle></mtd></mtr></mtable><mo fence=true>]</mo></mrow><mo stretchy=true>⏟</mo></munder><mi>A</mi></munder><mo>=</mo><munder><munder><mrow><mo fence=true>[</mo><mtable rowspacing=0.1600em columnalign="center center center" columnspacing=1em><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mn>0</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mn>0.25</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>0</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>1</mn></mstyle></mtd></mtr></mtable><mo fence=true>]</mo></mrow><mo stretchy=true>⏟</mo></munder><mi>L</mi></munder><munder><munder><mrow><mo fence=true>[</mo><mtable rowspacing=0.1600em columnalign="center center center" columnspacing=1em><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mn>4</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>4</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mrow><mo>−</mo><mn>3</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>4</mn></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mrow><mo>−</mo><mn>1</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=false><mn>1.75</mn></mstyle></mtd></mtr></mtable><mo fence=true>]</mo></mrow><mo stretchy=true>⏟</mo></munder><mi>U</mi></munder></mrow><annotation encoding="application/x-tex">\underbrace{\left[\begin{array}{c c c} 4 & 4 & -3 \\ 0 & 4 & -1 \\ 1 & 1 & 1 \end{array}\right]}_{A} = \underbrace{\left[\begin{array}{c c c} 1 & & \\ 0 & 1 & \\ 0.25 & 0 & 1 \end{array}\right]}_{L} \underbrace{\left[\begin{array}{c c c} 4 & 4 & -3 \\ & 4 & -1 \\ & & 1.75 \end{array}\right]}_{U}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:4.926371em;vertical-align:-2.876351em;></span><span class="mord munder"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.0500199999999995em;><span style=top:-1.1736689999999999em;><span class=pstrut style=height:4.05002em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span style=top:-4.05002em;><span class=pstrut style=height:4.05002em;></span><span class="mord munder"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span class=svg-align style=top:-1.8519999999999999em;><span class=pstrut style=height:4.05002em;></span><span class=stretchy style=height:0.548em;min-width:1.6em;><span class=brace-left style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMinYMin slice"><path d="M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13
35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688
0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7
-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z"></path></svg></span><span class=brace-center style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMidYMin slice"><path d="M199572 214
c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14
53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3
11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0
-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z"></path></svg></span><span class=brace-right style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMaxYMin slice"><path d="M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3
28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237
-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z"></path></svg></span></span></span><span style=top:-4.05002em;><span class=pstrut style=height:4.05002em;></span><span class=mord><span class=minner><span class=mopen><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span style=top:-2.2500000000000004em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style=top:-3.3970000000000002em;><span class=pstrut style=height:3.1550000000000002em;></span><span style=height:0.016em;width:0.667em;><svg xmlns="http://www.w3.org/2000/svg" width=0.667em height=0.016em style=width:0.667em viewBox="0 0 667 16" preserveAspectRatio=xMinYMin><path d="M319 0 H403 V16 H319z M319 0 H403 V16 H319z"></path></svg></span></span><span style=top:-4.05002em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.55002em;><span></span></span></span></span></span></span><span class=mord><span class=mtable><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>0</span></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>−</span><span class=mord>3</span></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>−</span><span class=mord>1</span></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span></span></span><span class=mclose><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span style=top:-2.2500000000000004em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style=top:-3.3970000000000002em;><span class=pstrut style=height:3.1550000000000002em;></span><span style=height:0.016em;width:0.667em;><svg xmlns="http://www.w3.org/2000/svg" width=0.667em height=0.016em style=width:0.667em viewBox="0 0 667 16" preserveAspectRatio=xMinYMin><path d="M263 0 H347 V16 H263z M263 0 H347 V16 H263z"></path></svg></span></span><span style=top:-4.05002em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.55002em;><span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.19802em;><span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.876351em;><span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:4.926371em;vertical-align:-2.876351em;></span><span class="mord munder"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.0500199999999995em;><span style=top:-1.1736689999999999em;><span class=pstrut style=height:4.05002em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">L</span></span></span></span><span style=top:-4.05002em;><span class=pstrut style=height:4.05002em;></span><span class="mord munder"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span class=svg-align style=top:-1.8519999999999999em;><span class=pstrut style=height:4.05002em;></span><span class=stretchy style=height:0.548em;min-width:1.6em;><span class=brace-left style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMinYMin slice"><path d="M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13
35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688
0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7
-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z"></path></svg></span><span class=brace-center style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMidYMin slice"><path d="M199572 214
c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14
53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3
11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0
-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z"></path></svg></span><span class=brace-right style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMaxYMin slice"><path d="M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3
28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237
-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z"></path></svg></span></span></span><span style=top:-4.05002em;><span class=pstrut style=height:4.05002em;></span><span class=mord><span class=minner><span class=mopen><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span style=top:-2.2500000000000004em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style=top:-3.3970000000000002em;><span class=pstrut style=height:3.1550000000000002em;></span><span style=height:0.016em;width:0.667em;><svg xmlns="http://www.w3.org/2000/svg" width=0.667em height=0.016em style=width:0.667em viewBox="0 0 667 16" preserveAspectRatio=xMinYMin><path d="M319 0 H403 V16 H319z M319 0 H403 V16 H319z"></path></svg></span></span><span style=top:-4.05002em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.55002em;><span></span></span></span></span></span></span><span class=mord><span class=mtable><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>0</span></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>0.25</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>0</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span></span></span><span class=mclose><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span style=top:-2.2500000000000004em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style=top:-3.3970000000000002em;><span class=pstrut style=height:3.1550000000000002em;></span><span style=height:0.016em;width:0.667em;><svg xmlns="http://www.w3.org/2000/svg" width=0.667em height=0.016em style=width:0.667em viewBox="0 0 667 16" preserveAspectRatio=xMinYMin><path d="M263 0 H347 V16 H263z M263 0 H347 V16 H263z"></path></svg></span></span><span style=top:-4.05002em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.55002em;><span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.19802em;><span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.876351em;><span></span></span></span></span></span><span class="mord munder"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.0500199999999995em;><span style=top:-1.1736689999999999em;><span class=pstrut style=height:4.05002em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.10903em;>U</span></span></span></span><span style=top:-4.05002em;><span class=pstrut style=height:4.05002em;></span><span class="mord munder"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span class=svg-align style=top:-1.8519999999999999em;><span class=pstrut style=height:4.05002em;></span><span class=stretchy style=height:0.548em;min-width:1.6em;><span class=brace-left style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMinYMin slice"><path d="M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13
35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688
0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7
-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z"></path></svg></span><span class=brace-center style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMidYMin slice"><path d="M199572 214
c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14
53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3
11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0
-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z"></path></svg></span><span class=brace-right style=height:0.548em;><svg xmlns="http://www.w3.org/2000/svg" width=400em height=0.548em viewBox="0 0 400000 548" preserveAspectRatio="xMaxYMin slice"><path d="M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3
28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237
-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z"></path></svg></span></span></span><span style=top:-4.05002em;><span class=pstrut style=height:4.05002em;></span><span class=mord><span class=minner><span class=mopen><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span style=top:-2.2500000000000004em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style=top:-3.3970000000000002em;><span class=pstrut style=height:3.1550000000000002em;></span><span style=height:0.016em;width:0.667em;><svg xmlns="http://www.w3.org/2000/svg" width=0.667em height=0.016em style=width:0.667em viewBox="0 0 667 16" preserveAspectRatio=xMinYMin><path d="M319 0 H403 V16 H319z M319 0 H403 V16 H319z"></path></svg></span></span><span style=top:-4.05002em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.55002em;><span></span></span></span></span></span></span><span class=mord><span class=mtable><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span><span class=arraycolsep style=width:0.5em;></span><span class=col-align-c><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05em;><span style=top:-4.21em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>−</span><span class=mord>3</span></span></span><span style=top:-3.0099999999999993em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>−</span><span class=mord>1</span></span></span><span style=top:-1.8099999999999994em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1.75</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.5500000000000007em;><span></span></span></span></span></span><span class=arraycolsep style=width:0.5em;></span></span></span><span class=mclose><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.05002em;><span style=top:-2.2500000000000004em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style=top:-3.3970000000000002em;><span class=pstrut style=height:3.1550000000000002em;></span><span style=height:0.016em;width:0.667em;><svg xmlns="http://www.w3.org/2000/svg" width=0.667em height=0.016em style=width:0.667em viewBox="0 0 667 16" preserveAspectRatio=xMinYMin><path d="M263 0 H347 V16 H263z M263 0 H347 V16 H263z"></path></svg></span></span><span style=top:-4.05002em;><span class=pstrut style=height:3.1550000000000002em;></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.55002em;><span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.19802em;><span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.876351em;><span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>The method actually allows row pivoting, so in this case we should have
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo>=</mo><mi>P</mi><mi>L</mi><mi>U</mi></mrow><annotation encoding="application/x-tex">A = PLU</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal">A</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.13889em;>P</span><span class="mord mathnormal" style=margin-right:0.10903em;>LU</span></span></span></span> where the pivot matrix <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.68333em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.13889em;>P</span></span></span></span>
is just the identity matrix.</p>
<p>To actually call this method, we'll need to study the <a href="http://www.netlib.org/lapack/explore-html/">documentation</a>.
I learned software in the web development world, so I was used to "modern"
documentation like <code>readthedocs.org</code>. When I first saw the <a href="http://www.doxygen.nl/">Doxygen</a>-based
LAPACK docs, I was intimidated. It's a bit of a different style and many
URLs are not human readable (for example, the <a href="http://www.netlib.org/lapack/explore-html/dd/d9a/group__double_g_ecomputational_ga0019443faea08275ca60a734d0593e60.html">URL</a> for <code>dgetrf</code>).
In addition, the arguments often have short or abbreviated names that can be
hard to parse and each argument has an <strong>intent</strong> of <code>in</code>, <code>out</code> or <code>inout</code>.
The concept of an argument's intent is a Fortran feature and at first I
didn't understand the purpose of it.</p>
<p>Let's break down the arguments to <code>dgetrf</code>:</p>
<p><strong>Constant Inputs</strong>:</p>
<ul>
<li><code>M</code> is an <code>integer</code>; the number of rows in the matrix <code>A</code>.</li>
<li><code>N</code> is an <code>integer</code>; the number of columns in the matrix <code>A</code>.</li>
<li><code>LDA</code> is an <code>integer</code>; the leading dimension (<strong>LD</strong>) of <code>A</code>. This would
initially seem to be redundant since the number of rows <code>M</code> should be
the leading dimension. However, by allowing <code>LDA</code> (the stride) to be
different from <code>M</code>, <code>A</code> can be taken as a submatrix of a larger array without
having to copy the data.</li>
</ul>
<p><strong>Outputs</strong>:</p>
<ul>
<li><code>IPIV</code> is a vector of <code>integer</code> values of dimension <code>min(M, N)</code>; it describes
the row pivots used and is a more compact representation of the matrix <code>P</code>.</li>
<li><code>INFO</code> is an <code>integer</code>; this returns <code>0</code> if the method succeeded,
uses negative return values to indicate invalid inputs (e.g. a matrix can't
have <code>N = -2</code> rows) and positive return values to indicate if a division
by zero occurred during Gaussian elimination.</li>
</ul>
<p><strong>Mutated Inputs</strong> (i.e. intent <code>inout</code>):</p>
<ul>
<li><code>A</code> is a 2D array of <code>double</code> precision values of dimension <code>LDA x N</code>;
on input this is the matrix that is being factored. When the routine exits,
the lower triangle of <code>A</code> will contain the below diagonal elements of <code>L</code>
(the diagonal of <code>L</code> is already known to be all ones) and the upper triangle
of <code>A</code> will contain <code>U</code>.</li>
</ul>
<p>Since the original LAPACK implementation (and many current implementations)
are written in Fortran, all arguments are passed by reference.</p>
<h3 id=high-level-py>High-Level Python</h3>
<p>There are two functions in SciPy for performing an LU decomposition:
<code>scipy.linalg.lapack.dgetrf</code> and <code>scipy.linalg.lu</code>. The former is a "direct"
wrapper but the wrapper handles allocating the outputs and allows a flag
<code>overwrite_a</code> which will determine if a copy of the input matrix is used
when computing the factorization. The other function <code>scipy.linalg.lu</code> varies
slightly, but not enough to warrant a separate discussion here.</p>
<p>Now, we'll call <code>dgetrf</code> with our sample matrix. To avoid any overhead
from copies we make sure <code>A</code> is in Fortran order (<code>"F"</code>) and set the
<code>overwrite_a</code> flag to <code>True</code>:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=kn>import</span> <span class=nn>numpy</span> <span class=k>as</span> <span class=nn>np</span>
<span class=o>>>></span> <span class=kn>import</span> <span class=nn>scipy.linalg.lapack</span>
<span class=o>>>></span> <span class=n>A</span> <span class=o>=</span> <span class=n>np</span><span class=o>.</span><span class=n>array</span><span class=p>([</span>
<span class=o>...</span> <span class=p>[</span><span class=mf>4.</span><span class=p>,</span> <span class=mf>4.</span><span class=p>,</span> <span class=o>-</span><span class=mf>3.</span><span class=p>],</span>
<span class=o>...</span> <span class=p>[</span><span class=mf>0.</span><span class=p>,</span> <span class=mf>4.</span><span class=p>,</span> <span class=o>-</span><span class=mf>1.</span><span class=p>],</span>
<span class=o>...</span> <span class=p>[</span><span class=mf>1.</span><span class=p>,</span> <span class=mf>1.</span><span class=p>,</span> <span class=mf>1.</span><span class=p>],</span>
<span class=o>...</span> <span class=p>],</span> <span class=n>order</span><span class=o>=</span><span class=s2>"F"</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>lu_mat</span><span class=p>,</span> <span class=n>ipiv</span><span class=p>,</span> <span class=n>info</span> <span class=o>=</span> <span class=n>scipy</span><span class=o>.</span><span class=n>linalg</span><span class=o>.</span><span class=n>lapack</span><span class=o>.</span><span class=n>dgetrf</span><span class=p>(</span><span class=n>A</span><span class=p>,</span> <span class=n>overwrite_a</span><span class=o>=</span><span class=kc>True</span><span class=p>)</span>
</code></pre></div>
<p>The method succeeded and the pivots are "trivial", i.e. the identity
matrix<sup id=sf-learn-you-a-lapack-2-back><a href=#sf-learn-you-a-lapack-2 class=simple-footnote title="Though SciPy has returned 0-based pivots rather than the 1-based indices returned from LAPACK)">2</a></sup></p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>info</span>
<span class=mi>0</span>
<span class=o>>>></span> <span class=n>ipiv</span>
<span class=n>array</span><span class=p>([</span><span class=mi>0</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>2</span><span class=p>],</span> <span class=n>dtype</span><span class=o>=</span><span class=n>int32</span><span class=p>)</span>
</code></pre></div>
<p>Our returned <code>lu_mat</code> is really just our input <code>A</code>, which has been mutated
to contain <code>L</code> and <code>U</code> in the lower and upper triangles:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>lu_mat</span> <span class=ow>is</span> <span class=n>A</span>
<span class=kc>True</span>
<span class=o>>>></span> <span class=n>A</span>
<span class=n>array</span><span class=p>([[</span> <span class=mf>4.</span> <span class=p>,</span> <span class=mf>4.</span> <span class=p>,</span> <span class=o>-</span><span class=mf>3.</span> <span class=p>],</span>
<span class=p>[</span> <span class=mf>0.</span> <span class=p>,</span> <span class=mf>4.</span> <span class=p>,</span> <span class=o>-</span><span class=mf>1.</span> <span class=p>],</span>
<span class=p>[</span> <span class=mf>0.25</span><span class=p>,</span> <span class=mf>0.</span> <span class=p>,</span> <span class=mf>1.75</span><span class=p>]])</span>
</code></pre></div>
<h3 id=finding-lapack>Finding LAPACK</h3>
<blockquote>
<p>This section can be freely skipped. <strong>TL;DR</strong>: the <code>liblapack</code> shared library
contains the routine <code>dgetrf_</code>. In other words, the name in the symbol table
has an underscore appended to it.</p>
</blockquote>
<p>Before moving on to C, C++ and other low-level languages we need to
understand the exported interface of LAPACK. To do this, we'll get
a little help from the <code>ctypes</code> <a href="https://docs.python.org/3/library/ctypes.html">library</a>:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=kn>import</span> <span class=nn>ctypes.util</span>
<span class=o>>>></span> <span class=n>ctypes</span><span class=o>.</span><span class=n>util</span><span class=o>.</span><span class=n>find_library</span><span class=p>(</span><span class=s2>"lapack"</span><span class=p>)</span>
<span class=s1>'liblapack.so.3'</span>
</code></pre></div>
<p>Viewing the <a href="https://github.com/python/cpython/blob/v3.7.0/Lib/ctypes/util.py#L309-L312">source</a> in the Python standard library, we see that (on
"most" posix systems) this is essentially equivalent to a direct usage
of <code>ldconfig</code>:</p>
<div class=highlight><pre><span></span><code>$ <span class=nv>LC_ALL</span><span class=o>=</span>C <span class=nv>LANG</span><span class=o>=</span>C ldconfig -p <span class=p>|</span> grep <span class=s1>'liblapack\.'</span>
liblapack.so.3 <span class=o>(</span>libc6,x86-64<span class=o>)</span> <span class=o>=</span>> /usr/lib/x86_64-linux-gnu/liblapack.so.3
liblapack.so <span class=o>(</span>libc6,x86-64<span class=o>)</span> <span class=o>=</span>> /usr/lib/x86_64-linux-gnu/liblapack.so
</code></pre></div>
<p>If that fails, including <code>-llapack</code> when compiling an empty file
with <code>gcc</code> is used:</p>
<div class=highlight><pre><span></span><code>$ <span class=nv>LC_ALL</span><span class=o>=</span>C <span class=nv>LANG</span><span class=o>=</span>C gcc -Wl,-t -o /dev/null -llapack <span class=m>2</span>> /dev/null <span class=p>|</span> grep lapack
-llapack <span class=o>(</span>/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/liblapack.so<span class=o>)</span>
$ objdump -p -j .dynamic <span class=se>\</span>
> /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/liblapack.so <span class=se>\</span>
> <span class=m>2</span>> /dev/null <span class=p>|</span> grep SONAME
SONAME liblapack.so.3
</code></pre></div>
<p>If that also fails, <code>ld</code> (possibly extended by
the <code>LD_LIBRARY_PATH</code> environment variable) is used:</p>
<div class=highlight><pre><span></span><code>$ ld -t -llapack <span class=m>2</span>> /dev/null
ld: mode elf_x86_64
-llapack <span class=o>(</span>//usr/lib/x86_64-linux-gnu/liblapack.so<span class=o>)</span>
$ objdump -p -j .dynamic <span class=se>\</span>
> //usr/lib/x86_64-linux-gnu/liblapack.so <span class=se>\</span>
> <span class=m>2</span>> /dev/null <span class=p>|</span> grep SONAME
SONAME liblapack.so.3
</code></pre></div>
<p>Once we've found the shared library, we need to look in the symbol table
(<code>-T</code> for table) for <code>dgetrf</code>:</p>
<div class=highlight><pre><span></span><code>$ objdump -T /usr/lib/x86_64-linux-gnu/liblapack.so <span class=p>|</span> grep -i dgetrf
00000000001273d0 g DF .text <span class=m>0000000000000158</span> Base clapack_dgetrf
000000000002c520 g DF .text <span class=m>0000000000000025</span> Base ATL_dgetrf
<span class=m>0000000000036630</span> g DF .text 00000000000000d4 Base atl_f77wrap_dgetrf_
000000000002c550 g DF .text <span class=m>0000000000000778</span> Base ATL_dgetrfC
000000000002ccd0 g DF .text 00000000000002e0 Base ATL_dgetrfR
<span class=m>0000000000215590</span> g DF .text 00000000000000b3 Base dgetrf_
<span class=m>0000000000215650</span> g DF .text <span class=m>0000000000000490</span> Base dgetrf2_
</code></pre></div>
<p>We see that there are quite a few <code>dgetrf</code> routines, but the one we'll use
is <code>dgetrf_</code>. The <code>dgetrf2_</code> routine is a recursive <a href="http://www.netlib.org/lapack/explore-html/dd/d9a/group__double_g_ecomputational_gabdd3af29e9f6bbaf4b352341a1e8b464.html#gabdd3af29e9f6bbaf4b352341a1e8b464">version</a> of <code>dgetrf_</code>
and the other routines are implementation details (specifically <a href="http://www.netlib.org/clapack/readme">CLAPACK</a>
and <a href="http://math-atlas.sourceforge.net/">ATLAS</a>).</p>
<p>This symbol name was a bit confusing to me when using LAPACK, but I took it
on faith. The reason for it is <a href="https://www.math.utah.edu/software/c-with-fortran.html#routine-naming">historical</a>:</p>
<blockquote>
<p>The world's first Fortran 77 compiler ...
appended an underscore on Fortran external names. Thus, Fortran
<code>SUBROUTINE foo</code> is known as <code>foo_()</code> in C</p>
</blockquote>
<p>This convention has remained even as compilers have changed. For example
CLAPACK (i.e. an implementation of LAPACK in C) follows this convention
even though no Fortran compiler is used at all:</p>
<blockquote>
<p><code>f2c</code> has added this underscore to all the names in CLAPACK. So,
a call that in Fortran would look like: <code>call dgetrf(...)</code> becomes in C:
<code>dgetrf_(...);</code></p>
</blockquote>
<p>Now that we understand the shared library, let's actually figure out where
it came from. Following the symbolic links we see</p>
<div class=highlight><pre><span></span><code><span class=o>/</span><span class=n>usr</span><span class=o>/</span><span class=n>lib</span><span class=o>/</span><span class=n>x86_64</span><span class=o>-</span><span class=n>linux</span><span class=o>-</span><span class=n>gnu</span><span class=o>/</span><span class=n>liblapack</span><span class=p>.</span><span class=n>so</span><span class=mf>.3</span>
<span class=o>-></span> <span class=o>/</span><span class=n>etc</span><span class=o>/</span><span class=n>alternatives</span><span class=o>/</span><span class=n>liblapack</span><span class=p>.</span><span class=n>so</span><span class=mf>.3</span><span class=o>-</span><span class=n>x86_64</span><span class=o>-</span><span class=n>linux</span><span class=o>-</span><span class=n>gnu</span>
<span class=o>-></span> <span class=o>/</span><span class=n>usr</span><span class=o>/</span><span class=n>lib</span><span class=o>/</span><span class=n>x86_64</span><span class=o>-</span><span class=n>linux</span><span class=o>-</span><span class=n>gnu</span><span class=o>/</span><span class=n>atlas</span><span class=o>/</span><span class=n>liblapack</span><span class=p>.</span><span class=n>so</span><span class=mf>.3</span>
<span class=o>-></span> <span class=o>/</span><span class=n>usr</span><span class=o>/</span><span class=n>lib</span><span class=o>/</span><span class=n>x86_64</span><span class=o>-</span><span class=n>linux</span><span class=o>-</span><span class=n>gnu</span><span class=o>/</span><span class=n>atlas</span><span class=o>/</span><span class=n>liblapack</span><span class=p>.</span><span class=n>so</span><span class=mf>.3.10.3</span>
</code></pre></div>
<p>Once the true location is given, we can find<sup id=sf-learn-you-a-lapack-3-back><a href=#sf-learn-you-a-lapack-3 class=simple-footnote title="On a Debian Linux. For example, I am running Ubuntu 18.04">3</a></sup> the package that owns the
shared library</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>dpkg-query -S /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3.10.3
<span class=go>libatlas3-base:amd64: /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3.10.3</span>
<span class=gp>$ </span><span class=c1># Find ATLAS reverse dependencies of libatlas3-base package</span>
<span class=gp>$ </span>apt rdepends libatlas3-base <span class=m>2</span>> /dev/null <span class=p>|</span> grep Depends <span class=p>|</span> grep atlas
<span class=go> Depends: libatlas-base-dev (= 3.10.3-5)</span>
</code></pre></div>
<h3 id=low-level-py>Low-Level Python (<code>ctypes</code>)</h3>
<p>Now that we know which shared library to use, we can dynamically load
the library into Python and verify that <code>dgetrf_</code> is in the symbol table:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=kn>import</span> <span class=nn>ctypes</span>
<span class=o>>>></span> <span class=n>liblapack</span> <span class=o>=</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>cdll</span><span class=o>.</span><span class=n>LoadLibrary</span><span class=p>(</span><span class=s2>"liblapack.so.3"</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>liblapack</span><span class=o>.</span><span class=n>dgetrf_</span>
<span class=o><</span><span class=n>_FuncPtr</span> <span class=nb>object</span> <span class=n>at</span> <span class=mh>0x7f3fd33ba688</span><span class=o>></span>
</code></pre></div>
<p>We can also verify that the <code>dgetrf</code> symbol is <strong>not</strong> present (and the
traceback will show us the actual path to the shared library):</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>liblapack</span><span class=o>.</span><span class=n>dgetrf</span>
<span class=n>Traceback</span> <span class=p>(</span><span class=n>most</span> <span class=n>recent</span> <span class=n>call</span> <span class=n>last</span><span class=p>):</span>
<span class=n>File</span> <span class=s2>"<stdin>"</span><span class=p>,</span> <span class=n>line</span> <span class=mi>1</span><span class=p>,</span> <span class=ow>in</span> <span class=o><</span><span class=n>module</span><span class=o>></span>
<span class=n>File</span> <span class=s2>".../lib/python3.7/ctypes/__init__.py"</span><span class=p>,</span> <span class=n>line</span> <span class=mi>369</span><span class=p>,</span> <span class=ow>in</span> <span class=fm>__getattr__</span>
<span class=n>func</span> <span class=o>=</span> <span class=bp>self</span><span class=o>.</span><span class=fm>__getitem__</span><span class=p>(</span><span class=n>name</span><span class=p>)</span>
<span class=n>File</span> <span class=s2>".../lib/python3.7/ctypes/__init__.py"</span><span class=p>,</span> <span class=n>line</span> <span class=mi>374</span><span class=p>,</span> <span class=ow>in</span> <span class=fm>__getitem__</span>
<span class=n>func</span> <span class=o>=</span> <span class=bp>self</span><span class=o>.</span><span class=n>_FuncPtr</span><span class=p>((</span><span class=n>name_or_ordinal</span><span class=p>,</span> <span class=bp>self</span><span class=p>))</span>
<span class=ne>AttributeError</span><span class=p>:</span> <span class=o>/</span><span class=n>usr</span><span class=o>/</span><span class=n>lib</span><span class=o>/</span><span class=n>x86_64</span><span class=o>-</span><span class=n>linux</span><span class=o>-</span><span class=n>gnu</span><span class=o>/</span><span class=n>liblapack</span><span class=o>.</span><span class=n>so</span><span class=mf>.3</span><span class=p>:</span> <span class=n>undefined</span> <span class=n>symbol</span><span class=p>:</span> <span class=n>dgetrf</span>
</code></pre></div>
<p>To actually call this routine, we first specify the input and output types:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>dgetrf</span> <span class=o>=</span> <span class=n>liblapack</span><span class=o>.</span><span class=n>dgetrf_</span>
<span class=o>>>></span> <span class=n>int_ptr</span> <span class=o>=</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>POINTER</span><span class=p>(</span><span class=n>ctypes</span><span class=o>.</span><span class=n>c_int</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>double_ptr</span> <span class=o>=</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>POINTER</span><span class=p>(</span><span class=n>ctypes</span><span class=o>.</span><span class=n>c_double</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>dgetrf</span><span class=o>.</span><span class=n>argtypes</span> <span class=o>=</span> <span class=p>[</span><span class=n>int_ptr</span><span class=p>,</span> <span class=n>int_ptr</span><span class=p>,</span> <span class=n>double_ptr</span><span class=p>,</span> <span class=n>int_ptr</span><span class=p>,</span> <span class=n>int_ptr</span><span class=p>,</span> <span class=n>int_ptr</span><span class=p>]</span>
<span class=o>>>></span> <span class=n>dgetrf</span><span class=o>.</span><span class=n>restype</span> <span class=o>=</span> <span class=kc>None</span>
</code></pre></div>
<p>To call it, we use <code>ctypes</code> and NumPy to allocate all of our arguments:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=kn>import</span> <span class=nn>numpy</span> <span class=k>as</span> <span class=nn>np</span>
<span class=o>>>></span> <span class=n>M</span> <span class=o>=</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>c_int</span><span class=p>(</span><span class=mi>3</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>N</span> <span class=o>=</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>c_int</span><span class=p>(</span><span class=mi>3</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>A</span> <span class=o>=</span> <span class=n>np</span><span class=o>.</span><span class=n>array</span><span class=p>([</span>
<span class=o>...</span> <span class=p>[</span><span class=mf>4.</span><span class=p>,</span> <span class=mf>4.</span><span class=p>,</span> <span class=o>-</span><span class=mf>3.</span><span class=p>],</span>
<span class=o>...</span> <span class=p>[</span><span class=mf>0.</span><span class=p>,</span> <span class=mf>4.</span><span class=p>,</span> <span class=o>-</span><span class=mf>1.</span><span class=p>],</span>
<span class=o>...</span> <span class=p>[</span><span class=mf>1.</span><span class=p>,</span> <span class=mf>1.</span><span class=p>,</span> <span class=mf>1.</span><span class=p>],</span>
<span class=o>...</span> <span class=p>],</span> <span class=n>order</span><span class=o>=</span><span class=s2>"F"</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>LDA</span> <span class=o>=</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>c_int</span><span class=p>(</span><span class=mi>3</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>IPIV</span> <span class=o>=</span> <span class=n>np</span><span class=o>.</span><span class=n>empty</span><span class=p>(</span><span class=mi>3</span><span class=p>,</span> <span class=n>dtype</span><span class=o>=</span><span class=n>np</span><span class=o>.</span><span class=n>intc</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>INFO</span> <span class=o>=</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>c_int</span><span class=p>()</span>
<span class=o>>>></span> <span class=c1># Check Uninitialized</span>
<span class=o>>>></span> <span class=n>IPIV</span>
<span class=n>array</span><span class=p>([</span><span class=mi>47155696</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>2</span><span class=p>],</span> <span class=n>dtype</span><span class=o>=</span><span class=n>int32</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>INFO</span>
<span class=n>c_int</span><span class=p>(</span><span class=mi>50221552</span><span class=p>)</span>
</code></pre></div>
<p>Since LAPACK follows the pass by reference convention, we pass
in a pointer to each of these arguments</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>return_value</span> <span class=o>=</span> <span class=n>dgetrf</span><span class=p>(</span>
<span class=o>...</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>pointer</span><span class=p>(</span><span class=n>M</span><span class=p>),</span>
<span class=o>...</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>pointer</span><span class=p>(</span><span class=n>N</span><span class=p>),</span>
<span class=o>...</span> <span class=n>A</span><span class=o>.</span><span class=n>ctypes</span><span class=o>.</span><span class=n>data_as</span><span class=p>(</span><span class=n>double_ptr</span><span class=p>),</span>
<span class=o>...</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>pointer</span><span class=p>(</span><span class=n>LDA</span><span class=p>),</span>
<span class=o>...</span> <span class=n>IPIV</span><span class=o>.</span><span class=n>ctypes</span><span class=o>.</span><span class=n>data_as</span><span class=p>(</span><span class=n>int_ptr</span><span class=p>),</span>
<span class=o>...</span> <span class=n>ctypes</span><span class=o>.</span><span class=n>pointer</span><span class=p>(</span><span class=n>INFO</span><span class=p>),</span>
<span class=o>...</span> <span class=p>)</span>
</code></pre></div>
<p>and the results match those from <code>scipy.linalg.lapack.dgetrf</code>:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=n>return_value</span> <span class=ow>is</span> <span class=kc>None</span>
<span class=kc>True</span>
<span class=o>>>></span> <span class=n>INFO</span>
<span class=n>c_int</span><span class=p>(</span><span class=mi>0</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>IPIV</span>
<span class=n>array</span><span class=p>([</span><span class=mi>1</span><span class=p>,</span> <span class=mi>2</span><span class=p>,</span> <span class=mi>3</span><span class=p>],</span> <span class=n>dtype</span><span class=o>=</span><span class=n>int32</span><span class=p>)</span>
<span class=o>>>></span> <span class=n>A</span>
<span class=n>array</span><span class=p>([[</span> <span class=mf>4.</span> <span class=p>,</span> <span class=mf>4.</span> <span class=p>,</span> <span class=o>-</span><span class=mf>3.</span> <span class=p>],</span>
<span class=p>[</span> <span class=mf>0.</span> <span class=p>,</span> <span class=mf>4.</span> <span class=p>,</span> <span class=o>-</span><span class=mf>1.</span> <span class=p>],</span>
<span class=p>[</span> <span class=mf>0.25</span><span class=p>,</span> <span class=mf>0.</span> <span class=p>,</span> <span class=mf>1.75</span><span class=p>]])</span>
</code></pre></div>
<h3 id=c>C</h3>
<p>Unfortunately, LAPACK doesn't come with a standard header file, so
the <code>dgetrf_</code> symbol must be declared via <code>extern</code>:</p>
<div class=highlight><pre><span></span><code><span class=k>extern</span> <span class=kt>void</span> <span class=nf>dgetrf_</span><span class=p>(</span><span class=k>const</span> <span class=kt>int</span><span class=o>*</span> <span class=n>M</span><span class=p>,</span> <span class=k>const</span> <span class=kt>int</span><span class=o>*</span> <span class=n>N</span><span class=p>,</span> <span class=kt>double</span><span class=o>*</span> <span class=n>A</span><span class=p>,</span> <span class=k>const</span> <span class=kt>int</span><span class=o>*</span> <span class=n>LDA</span><span class=p>,</span>
<span class=kt>int</span><span class=o>*</span> <span class=n>IPIV</span><span class=p>,</span> <span class=kt>int</span><span class=o>*</span> <span class=n>INFO</span><span class=p>);</span>
</code></pre></div>
<p>Notice that all arguments are pointers. We've marked the input only arguments
as <code>const</code> to help the C compiler out. We've also used <code>int</code> (rather than
<code>long</code>) for the integer arguments.</p>
<p>When calling <code>dgetrf_</code> in the C <a href="/code/dgetrf_example.c">example</a>, we take
care to lay out <code>A</code> in Fortran order:</p>
<div class=highlight><pre><span></span><code><span class=kt>int</span> <span class=n>M</span> <span class=o>=</span> <span class=mi>3</span><span class=p>;</span>
<span class=kt>int</span> <span class=n>N</span> <span class=o>=</span> <span class=mi>3</span><span class=p>;</span>
<span class=kt>double</span> <span class=n>A</span><span class=p>[</span><span class=mi>9</span><span class=p>]</span> <span class=o>=</span> <span class=p>{</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>0</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>4</span><span class=p>,</span> <span class=mi>1</span><span class=p>,</span> <span class=mi>-3</span><span class=p>,</span> <span class=mi>-1</span><span class=p>,</span> <span class=mi>1</span> <span class=p>};</span>
<span class=kt>int</span> <span class=n>LDA</span> <span class=o>=</span> <span class=mi>3</span><span class=p>;</span>
<span class=kt>int</span> <span class=n>IPIV</span><span class=p>[</span><span class=mi>3</span><span class=p>];</span>
<span class=kt>int</span> <span class=n>INFO</span><span class=p>;</span>
</code></pre></div>
<p>Actually building code that uses <code>liblapack</code> confused me. On a Debian-based
Linux system, I could install LAPACK via</p>
<div class=highlight><pre><span></span><code><span class=err>$</span><span class=w> </span><span class=o>[</span><span class=n>sudo</span><span class=o>]</span><span class=w> </span><span class=n>apt</span><span class=w> </span><span class=n>install</span><span class=w> </span><span class=n>libatlas</span><span class=o>-</span><span class=n>base</span><span class=o>-</span><span class=n>dev</span><span class=w></span>
</code></pre></div>
<p>and be on my merry way with the <code>-llapack</code> flag:</p>
<div class=highlight><pre><span></span><code>$ gcc -o main dgetrf_example.c -llapack
$ ./main
Inputs:
<span class=nv>M</span> <span class=o>=</span> <span class=m>3</span>
<span class=nv>N</span> <span class=o>=</span> <span class=m>3</span>
<span class=nv>A</span> <span class=o>=</span> <span class=o>[</span> <span class=m>4</span>.00, <span class=m>4</span>.00, -3.00<span class=o>]</span>
<span class=o>[</span> <span class=m>0</span>.00, <span class=m>4</span>.00, -1.00<span class=o>]</span>
<span class=o>[</span> <span class=m>1</span>.00, <span class=m>1</span>.00, <span class=m>1</span>.00<span class=o>]</span>
<span class=nv>LDA</span> <span class=o>=</span> <span class=m>3</span>
Outputs:
<span class=nv>A</span> <span class=o>=</span> <span class=o>[</span> <span class=m>4</span>.00, <span class=m>4</span>.00, -3.00<span class=o>]</span>
<span class=o>[</span> <span class=m>0</span>.00, <span class=m>4</span>.00, -1.00<span class=o>]</span>
<span class=o>[</span> <span class=m>0</span>.25, <span class=m>0</span>.00, <span class=m>1</span>.75<span class=o>]</span>
<span class=nv>IPIV</span> <span class=o>=</span> <span class=o>[</span><span class=m>1</span>, <span class=m>2</span>, <span class=m>3</span><span class=o>]</span>
<span class=nv>INFO</span> <span class=o>=</span> <span class=m>0</span>
</code></pre></div>
<h3 id=compiling-on-os-x>Compiling on OS X</h3>
<blockquote>
<p><strong>TL;DR</strong>: As of macOS High Sierra (10.13), your code can link to LAPACK
via <code>-llapack</code> or <code>-framework Accelerate</code>. Also, when I started graduate
school I didn't know much about compiling code.</p>
</blockquote>
<p>I was using OS X Mountain Lion (10.8) at the time. Without
using Homebrew to install LAPACK or OpenBLAS, compiling<sup id=sf-learn-you-a-lapack-4-back><a href=#sf-learn-you-a-lapack-4 class=simple-footnote title="Note that gcc is just an alias for clang on OS X">4</a></sup> with <code>-llapack</code> failed with something
along the lines of:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>clang -o main dgetrf_example.c -llapack
<span class=go>ld: library not found for -llapack</span>
<span class=go>clang: error: linker command failed with exit code 1 (use -v to see invocation)</span>
</code></pre></div>
<p>Just leaving out the flag entirely was also not an option:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>clang -o main dgetrf_example.c
<span class=go>Undefined symbols for architecture x86_64:</span>
<span class=go> "_dgetrf_", referenced from:</span>
<span class=go> _main in dgetrf_example-fcd533.o</span>
<span class=go>ld: symbol(s) not found for architecture x86_64</span>
<span class=go>clang: error: linker command failed with exit code 1 (use -v to see invocation)</span>
</code></pre></div>
<p>I would eventually find out that Apple provides a custom <a href="https://developer.apple.com/documentation/accelerate/veclib">framework</a>
called <code>vecLib</code> that contained a LAPACK implementation / interface among other
things. So the correct magical incantation (as of OS X 10.8) was</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>clang -o main dgetrf_example.c -framework vecLib
</code></pre></div>
<p>At some point<sup id=sf-learn-you-a-lapack-5-back><a href=#sf-learn-you-a-lapack-5 class=simple-footnote title="It seems it was in OS X Yosemite (10.10).">5</a></sup>,
things <strong>got better</strong> (<a href="https://github.com/scipy/scipy/wiki/Dropping-support-for-Accelerate">thanks</a> Apple). On a current<sup id=sf-learn-you-a-lapack-6-back><a href=#sf-learn-you-a-lapack-6 class=simple-footnote title="macOS High Sierra (10.13)">6</a></sup> version, <code>liblapack</code> comes with the OS:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=kn>import</span> <span class=nn>ctypes.util</span>
<span class=o>>>></span> <span class=n>ctypes</span><span class=o>.</span><span class=n>util</span><span class=o>.</span><span class=n>find_library</span><span class=p>(</span><span class=s2>"lapack"</span><span class=p>)</span>
<span class=s1>'/usr/lib/liblapack.dylib'</span>
</code></pre></div>
<p>Following symlinks, we see that this shared library is part of the
<code>Accelerate</code> <a href="https://developer.apple.com/documentation/accelerate">framework</a>:</p>
<div class=highlight><pre><span></span><code><span class=o>>>></span> <span class=kn>import</span> <span class=nn>os</span>
<span class=o>>>></span> <span class=n>os</span><span class=o>.</span><span class=n>path</span><span class=o>.</span><span class=n>realpath</span><span class=p>(</span><span class=s2>"/usr/lib/liblapack.dylib"</span><span class=p>)</span>
<span class=s1>'/System/Library/Frameworks/Accelerate.framework/.../A/libLAPACK.dylib'</span>
</code></pre></div>
<!---
Full path:
'/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib'
-->
<p>Now <code>vecLib</code> is contained in <code>Accelerate</code> and can no longer be
included directly:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>readlink /System/Library/Frameworks/vecLib.framework
<span class=go>Accelerate.framework//Versions/A/Frameworks/vecLib.framework</span>
<span class=gp>$ </span>clang -o main dgetrf_example.c -framework vecLib
<span class=go>ld: cannot link directly with /System/Library/Frameworks//vecLib.framework/vecLib for architecture x86_64</span>
<span class=go>clang: error: linker command failed with exit code 1 (use -v to see invocation)</span>
</code></pre></div>
<p>However, this means that LAPACK can be included the "Linux" way or via
a framework:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>clang -o main dgetrf_example.c -llapack
<span class=gp>$ </span>clang -o main dgetrf_example.c -framework Accelerate
</code></pre></div>
<h3 id=cpp>C++</h3>
<blockquote>
<p><strong>TL;DR</strong>: Use <code>extern "C"</code> instead of just <code>extern</code> when declaring
LAPACK routines in C++ code.</p>
</blockquote>
<p>When I started graduate school I didn't know anything about shared libraries,
symbol tables, <a href="https://en.wikipedia.org/wiki/Name_mangling">name mangling</a> or ABIs. It also didn't even occur to me
that extra underscore in names of LAPACK routines in the shared library had
anything to do with those topics.</p>
<p>Luckily, after an hour or two<sup id=sf-learn-you-a-lapack-7-back><a href=#sf-learn-you-a-lapack-7 class=simple-footnote title="I'm not joking, I was really stumped">7</a></sup>
of Googling I learned about <code>extern "C"</code> and everything "made sense". Once
you know about <code>extern "C"</code>, declaring the LAPACK routine in C++ is essentially
the same as in C:</p>
<div class=highlight><pre><span></span><code><span class=k>extern</span> <span class=s>"C"</span> <span class=kt>void</span> <span class=n>dgetrf_</span><span class=p>(</span><span class=k>const</span> <span class=kt>int</span><span class=o>*</span> <span class=n>M</span><span class=p>,</span> <span class=k>const</span> <span class=kt>int</span><span class=o>*</span> <span class=n>N</span><span class=p>,</span> <span class=kt>double</span><span class=o>*</span> <span class=n>A</span><span class=p>,</span> <span class=k>const</span> <span class=kt>int</span><span class=o>*</span> <span class=n>LDA</span><span class=p>,</span>
<span class=kt>int</span><span class=o>*</span> <span class=n>IPIV</span><span class=p>,</span> <span class=kt>int</span><span class=o>*</span> <span class=n>INFO</span><span class=p>);</span>
</code></pre></div>
<p>From there, <code>dgetrf_</code> can be used as it would in C. But I'd like to explain
a bit further why we say <code>extern "C"</code> rather than <code>extern</code>. To explain,
consider the simple program that is valid in C or C++:</p>
<div class=highlight><pre><span></span><code><span class=kt>int</span> <span class=nf>together</span><span class=p>(</span><span class=kt>int</span> <span class=n>m</span><span class=p>,</span> <span class=kt>int</span> <span class=n>n</span><span class=p>)</span> <span class=p>{</span>
<span class=k>return</span> <span class=n>m</span> <span class=o>+</span> <span class=n>n</span><span class=p>;</span>
<span class=p>}</span>
</code></pre></div>
<p>If we compile this into an object file in C, we see the name <code>together</code>
in the symbol table</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>gcc -c together.c
<span class=gp>$ </span>nm together.o
<span class=go>0000000000000000 T together</span>
</code></pre></div>
<p>but if we compile the same code in C++, the name is mangled (to
<code>_Z8togetherii</code>) before it is put in the symbol table:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>g++ -c together.cpp
<span class=gp>$ </span>nm together.o
<span class=go>0000000000000000 T _Z8togetherii</span>
</code></pre></div>
<p>This name mangling allows many features of C++. For example, we could
provide a second implementation using the <strong>same</strong> name but with type
<code>double</code>:</p>
<div class=highlight><pre><span></span><code><span class=kt>double</span> <span class=nf>together</span><span class=p>(</span><span class=kt>double</span> <span class=n>m</span><span class=p>,</span> <span class=kt>double</span> <span class=n>n</span><span class=p>)</span> <span class=p>{</span>
<span class=k>return</span> <span class=n>m</span> <span class=o>+</span> <span class=n>n</span><span class=p>;</span>
<span class=p>}</span>
</code></pre></div>
<p>and the two functions can both be in the symbol table without "colliding"
on their shared name:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>g++ -c together.cpp
<span class=gp>$ </span>nm together.o
<span class=go>0000000000000014 T _Z8togetherdd</span>
<span class=go>0000000000000000 T _Z8togetherii</span>
</code></pre></div>
<p>For an example in the wild consider the <code>libjsoncpp</code> <a href="https://github.com/open-source-parsers/jsoncpp">package</a> (chosen at
random since it is installed on my current system). The <code>valueToString</code> method
in the <code>Json</code> namespace has six different implementations:</p>
<div class=highlight><pre><span></span><code><span class=gp>$ </span>objdump -T /usr/lib/x86_64-linux-gnu/libjsoncpp.so.1.7.4 <span class=p>|</span> grep valueToString
<span class=go>0000000000020c30 ... _ZN4Json13valueToStringB5cxx11Eb</span>
<span class=go>0000000000020be0 ... _ZN4Json13valueToStringB5cxx11Ed</span>
<span class=go>0000000000020b60 ... _ZN4Json13valueToStringB5cxx11Ei</span>
<span class=go>0000000000020ba0 ... _ZN4Json13valueToStringB5cxx11Ej</span>
<span class=go>00000000000208c0 ... _ZN4Json13valueToStringB5cxx11Ex</span>
<span class=go>0000000000020a80 ... _ZN4Json13valueToStringB5cxx11Ey</span>
<span class=gp>$ </span>objdump -C -T /usr/lib/x86_64-linux-gnu/libjsoncpp.so.1.7.4 <span class=p>|</span> grep valueToString
<span class=go>0000000000020c30 ... Json::valueToString[abi:cxx11](bool)</span>
<span class=go>0000000000020be0 ... Json::valueToString[abi:cxx11](double)</span>
<span class=go>0000000000020b60 ... Json::valueToString[abi:cxx11](int)</span>
<span class=go>0000000000020ba0 ... Json::valueToString[abi:cxx11](unsigned int)</span>
<span class=go>00000000000208c0 ... Json::valueToString[abi:cxx11](long long)</span>
<span class=go>0000000000020a80 ... Json::valueToString[abi:cxx11](unsigned long long)</span>
</code></pre></div>
<p>Why did I just tell you all this? To make it clear why we say <code>extern "C"</code>
instead of just <code>extern</code>. This indicates to the compiler that the symbol
we want to refer to is <strong>literally</strong> <code>dgetrf_</code>. By using <code>extern</code>, that would
tell the compiler to look for a mangled external name. For example with <code>g++</code>,
it would look for the name <code>_Z7dgetrf_PKiS0_PdS0_PiS2_</code>.</p>
<h3 id=conclusion>Conclusion</h3>
<p>I hope this post has been informational. Now you should have a better idea
how to</p>
<ul>
<li>Read LAPACK documentation to interpret and write the correct signature for
a LAPACK routine</li>
<li>Reference the correct symbol when calling a LAPACK routine as a foreign
function</li>
<li>Understand argument intent and pass by reference calling convention
for LAPACK's Fortran-like interface</li>
<li>Use Python's <code>ctypes</code> module (and NumPy's <code>ctypes.data_as</code> method) to
invoke LAPACK routines for fast prototyping and debugging</li>
</ul>
<p>Thanks for reading!</p><ol class=simple-footnotes><li id=sf-learn-you-a-lapack-1>This actually happened to me. My undergraduate research
project (REU) eventually boiled down to showing that a particularly special
matrix had a nonzero determinant. <a href=#sf-learn-you-a-lapack-1-back class=simple-footnote-back>↩</a></li><li id=sf-learn-you-a-lapack-2>Though SciPy has returned 0-based pivots rather than the 1-based
indices returned from LAPACK) <a href=#sf-learn-you-a-lapack-2-back class=simple-footnote-back>↩</a></li><li id=sf-learn-you-a-lapack-3>On a Debian Linux. For
example, I am running Ubuntu 18.04 <a href=#sf-learn-you-a-lapack-3-back class=simple-footnote-back>↩</a></li><li id=sf-learn-you-a-lapack-4>Note that <code>gcc</code> is
just an alias for <code>clang</code> on OS X <a href=#sf-learn-you-a-lapack-4-back class=simple-footnote-back>↩</a></li><li id=sf-learn-you-a-lapack-5>It <a href="https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16033">seems</a> it was in OS X Yosemite (10.10). <a href=#sf-learn-you-a-lapack-5-back class=simple-footnote-back>↩</a></li><li id=sf-learn-you-a-lapack-6>macOS High
Sierra (10.13) <a href=#sf-learn-you-a-lapack-6-back class=simple-footnote-back>↩</a></li><li id=sf-learn-you-a-lapack-7>I'm not joking, I was really stumped <a href=#sf-learn-you-a-lapack-7-back class=simple-footnote-back>↩</a></li></ol>Graduated2018-09-07T00:00:00-07:002018-09-07T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2018-09-07:/2018/09/graduated.html<p>After five years, I'm excited to say I've finished <a href="https://github.com/dhermes/phd-thesis">my PhD</a>. I certainly
learned a lot and met a lot of great people along the way.</p>
<p>One of the biggest lessons I learned was about myself: I need to <strong>say no</strong>
more often. I continued to say yes, to <a href="https://github.com/GoogleCloudPlatform/google-cloud-python/">side …</a></p><p>After five years, I'm excited to say I've finished <a href="https://github.com/dhermes/phd-thesis">my PhD</a>. I certainly
learned a lot and met a lot of great people along the way.</p>
<p>One of the biggest lessons I learned was about myself: I need to <strong>say no</strong>
more often. I continued to say yes, to <a href="https://github.com/GoogleCloudPlatform/google-cloud-python/">side projects</a>, to coffee in SF, to
teaching Python training on the side, etc. Saying no a bit more frequently
would have allowed me to spend more time on research and to finish sooner as
I'd originally hoped.</p>
<p>While the many diversions did make me appreciate the need for <strong>focus</strong>, I am
also happy that my time in school gave me an opportunity to go down rabbit
holes and winding paths to learn.</p>
<p>For readers in a hurry, the TL;DR:</p>
<ul>
<li><a href=#advising>Advising and Peers</a>: I was lucky to be in a great learning and
research environment</li>
<li><a href=#teaching>Teaching</a>: I enjoyed teaching undergraduates but wish some things
were different about the university model</li>
<li><a href=#research>Research</a>: I had a chance to make incremental progress on a tool
that can be useful for physical simulations</li>
<li><a href=#software>Software</a>: I wrote a lot of code both for science and for Google;
in particular, I learned to appreciate modern Fortran and struggled with
building binary extensions for Python</li>
</ul>
<h3 id=advising>Advising and Peers</h3>
<p>I was lucky to have a great advisor, <a href="http://persson.berkeley.edu">Per-Olof Persson</a>.
When I was deciding which graduate school to attend, a chat with Per
was one of the clinching factors in choosing UC Berkeley. Since his
research (CFD) was not quite in line with my interests (e.g. Numerical
Linear Algebra), I hesitated in asking him to advise me. However,
I gave the personality fit more weight than the research fit and am happy
about the outcome.</p>
<p>The UC Berkeley Math department is a very welcoming place and I really
enjoyed teaching undergraduates and taking classes with my fellow
graduate students. A few of my peers had somewhat inaccessible
advisors (e.g. they only met once a year) and these students did
feel a sense of <a href="http://www.fast.ai/2018/08/27/grad-school/">isolation</a>. It made a big difference having an advisor that
was easy to get in touch with and eager to help.</p>
<h3 id=teaching>Teaching</h3>
<p>I really enjoyed teaching and had some great interactions with students:</p>
<blockquote>
<p>Danny manages to be relaxed, funny, and watchable AND very knowledgeable
about the material AND a stickler about teaching it AND good at explaining
it clearly and quickly. This is a combination of strengths so rare around
here that I thought it was mythical.</p>
</blockquote>
<p>Though the interactions were great, there were a few things I wished were
different.</p>
<ul>
<li>I wish the lower-division classes were changed to utilize computers both
for rote computation and visualization of concepts. (I taught Calculus I and
II and Linear Algebra.)</li>
<li>I was a bit disappointed at the preparedness and more importantly the
enthusiasm of students in upper-division courses (I taught Numerical Analysis
five times). It seemed that for many, taking courses in their major was
a chore rather than a joy. This is as much (if not more) a reflection on the
system as it is on the students.</li>
<li>Numerical Analysis is an opportunity to learn how "classical" algorithms
break down on a computer (i.e. in the presence of rounding). Having the
ability to program is a must to really solidify the concepts. However, once
a class hits 150 students, the grading must be "standardized". In this case,
that meant student evaluation was done via traditional pen and paper
assignments and exams. Coupled with the absence of a programming
prerequisite, this made the amount of <strong>computing</strong> in the class
a small fraction of the course.</li>
<li>I was continually frustrated by the prevalence of MATLAB usage in the
math department. MATLAB certainly has strengths, but its kitchen sink
approach to namespaces (similar to that of PHP) really makes it hard to
teach. Its lack of a packaging story and reliance on a proprietary IDE
makes it hard for students to understand what code "is" (or even <strong>where</strong>
it is on their filesystem). The IPython notebook was created at UC
Berkeley and I wish the math department would get on board. Perhaps more
relevantly, using MATLAB does little to prepare students for the real world
because it is used almost exclusively in academic or lab settings.</li>
</ul>
<h3 id=research>Research</h3>
<p>I enjoyed the research I did, but wish there was more time to keep doing it.
<sup id=sf-graduated-1-back><a href=#sf-graduated-1 class=simple-footnote title="I suppose there would be if I were to stay in academia, but that path is not for me">1</a></sup> I thoroughly enjoyed diving into Numerical Linear Algebra
papers and implementing some of the more classical results. The most satisfying
of course were the ones that took a few attempts to get right.</p>
<p>In my dissertation, I describe a method for solution transfer between
curved meshes. In layman's terms:</p>
<ul>
<li>A <strong>mesh</strong> is an approximation of some physical domain, e.g. the surface
of a frying pan (in 2D) or the wing of an airplane (in 3D)</li>
<li>A mesh is composed of small <strong>elements</strong> that are well understood, e.g.
triangles, rectangles, tetrahedra, cubes, etc.</li>
<li>A <strong>curved</strong> mesh is one in which the edges / faces of the elements are
allowed to curve</li>
<li>A <strong>solution</strong> (or field) on a mesh is a numerical representation of
some physical quantity, e.g. velocity, pressure, density or energy</li>
<li><strong>Solution transfer</strong> is the process of reintepreting (or interpolating)
a solution from one mesh onto another</li>
</ul>
<p>During commonly used simulation techniques, one or several physical quantities
are represented on a mesh and change over time according to some law
of physics (usually represented by a partial differential equation). When the
process involves a fluid (the F in CFD), it's common to allow the mesh to
"travel" over time with the fluid. For <a href="https://www.cs.cmu.edu/~tp517/papers/cardoze04bezier-b.pdf">example</a>, when simulating blood flow
within a rigid cavity (e.g. a heart or vein) the mesh can represent a membrane
that flows as the blood moves.</p>
<p>In such simulations, the mesh can become tangled after a certain amount of
time moving along the flow. It is these cases where mesh quality begins to
deteroriate that benefit from <strong>solution transfer</strong>. Once a mesh becomes too
low-quality to use in simulation, a new mesh must be used to represent the
physical domain. Once the new mesh is chosen, the physical quantities being
tracked must be transferred from the low-quality mesh to the new one.</p>
<p>This work was certainly incremental, as much research is. Solution transfer
has already been <a href="https://doi.org/10.1016/j.cma.2010.07.015">described</a> for straight sided meshes (i.e. meshes
where the elements are not curved). However, the work required to intersect
curved triangles is considerably more involved than that required to
intersect straight sided triangles. Peter Thiel would have you
believe (in <a href="https://en.wikipedia.org/wiki/Zero_to_One">Zero to One</a>) that the hardest step is the initial idea and
everything else is incremental. However, I can say that the incremental
step from straight sided to curved elements was a <strong>considerable</strong> jump in
difficulty.</p>
<h3 id=software>Software</h3>
<p>During graduate school, I wrote a lot of code, as I usually do. However,
two projects in particular stick out:</p>
<ul>
<li>The <code>google-cloud-python</code> <a href="https://github.com/GoogleCloudPlatform/google-cloud-python/">collection</a> of packages</li>
<li>My <code>bezier</code> <a href="https://bezier.readthedocs.io/en/latest/">library</a> (<a href="http://joss.theoj.org/papers/10.21105/joss.00267">published</a> in JOSS)</li>
</ul>
<p>I've worked on Google client libraries in one form or another since 2011 and
somehow managed to keep doing this after leaving Google for UC Berkeley. I
had a great opportunity to be one of the main drivers of the
<code>google-cloud-python</code> library and it allowed me to stay current on how
software is built. Among other things I gained an appreciation for testing,
continuous integration and documentation that I didn't have before.</p>
<p>As part of my <a href=#research>research</a>, I needed to be able to intersect
millions of pairs of Bézier curves in a single simulation. I was worried
that doing this in my language of choice (Python) would be too slow, so I
decided to write the computation in a compiled language and wrap the interface
with a <a href="https://packaging.python.org/guides/packaging-binary-extensions/#an-overview-of-binary-extensions">binary extension</a>. Building binary wheels for Linux, Mac OS X and
Windows was a struggle, to say the least, but I'm happy I went through the
process. If I can find the time, I hope to write a bit more about some of
the amusing packaging bugs I created and had to track down. I hope that
<a href="https://scikit-build.readthedocs.io/en/latest/">scikit-build</a> or a similar effort can once and for all demystify the
process of invoking native code from Python.</p>
<p>I chose Fortran for the implementation, which is likely a shock to most
people outside of academia. In Silicon Valley, Fortran is usually a punchline
rather than a language choice. However, I discovered early in my program that
modern Fortran is a wonderful language. Writing vanilla Fortran is essentially
just like writing NumPy code with all square brackets (<code>[</code>) swapped
for parentheses (<code>(</code>). With the Fortran 90 specification, the FORTRAN (yes, all
caps) language was no more and the modern features actually make it an
appealing language.</p>
<p>I legitimately think people should consider Fortran first for computational
workloads, if not for more general purpose tasks. Having a sponsor has made
the Go (Google) and Rust (Firefox) communities vibrant places with great
documentation and ever-expanding choices for libraries. Intel is the closest
it comes to a Fortran steward due to their forums for the wonderful
<code>ifort</code> compiler. However, there is no community-led Fortran
documentation<sup id=sf-graduated-2-back><a href=#sf-graduated-2 class=simple-footnote title="An equivalent of golang.org or docs.python.org">2</a></sup>
and this makes it a bit hard to develop code in Fortran. The amazing
<code>fortran90</code> <a href="https://www.fortran90.org/">site</a> from Ondřej Čertík fills many gaps, but
is mostly a one-person effort.</p>
<p>I started the <code>foreign-fortran</code> <a href="https://foreign-fortran.readthedocs.io/en/latest/">project</a> to make my little contribution
back to the Fortran community. The project is essentially documentation only
and gives examples of how Fortran libraries can be used from other programming
languages.</p>
<h2>Parting Words</h2>
<p>I really enjoyed my time in graduate school and wish I was able to better
utilize the awesome communities on UC Berkeley's campus. Though I'm happy I
did it, I'm equally happy that I spent three years in the real world working
at companies<sup id=sf-graduated-3-back><a href=#sf-graduated-3 class=simple-footnote title="Or "industry" as it's called in academia">3</a></sup> before
starting. I would recommend that all undergraduate students go get a "real job"
before deciding to commit several years of their life to a PhD. There's a whole
world out there outside of the ivory tower and too often it's not clear to
students what their options are if they don't end up in that tenure track
job.</p>
<p>As I said, my fellow graduate students with and from whom I have learned were
a great part of the experience. In particular Will Pazner<sup id=sf-graduated-4-back><a href=#sf-graduated-4 class=simple-footnote title="Thanks to Will for reviewing this post">4</a></sup>, Chris Miller and Qiaochu Yuan as well as my
undergraduate classmate Wade Hindes have been a source of many great
discussions.</p><ol class=simple-footnotes><li id=sf-graduated-1>I suppose there would be if I were to stay in academia, but that path is
not for me <a href=#sf-graduated-1-back class=simple-footnote-back>↩</a></li><li id=sf-graduated-2>An equivalent of <code>golang.org</code> or <code>docs.python.org</code> <a href=#sf-graduated-2-back class=simple-footnote-back>↩</a></li><li id=sf-graduated-3>Or "industry" as it's called in academia <a href=#sf-graduated-3-back class=simple-footnote-back>↩</a></li><li id=sf-graduated-4>Thanks to Will
for reviewing this post <a href=#sf-graduated-4-back class=simple-footnote-back>↩</a></li></ol>Installing Python on OS X2017-09-19T00:00:00-07:002017-09-19T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2017-09-19:/2017/09/python-on-os-x.html<blockquote>
<p><strong>Caveat</strong>: I stopped using a Mac for my development machine way
back in the fall of 2014. You probably shouldn't listen to me.</p>
</blockquote>
<h3>What Not to Do</h3>
<p>The first rule of using Python on any operating system: <strong>don't use
system Python</strong>. The OS <strong>relies</strong> on that Python, including the packages …</p><blockquote>
<p><strong>Caveat</strong>: I stopped using a Mac for my development machine way
back in the fall of 2014. You probably shouldn't listen to me.</p>
</blockquote>
<h3>What Not to Do</h3>
<p>The first rule of using Python on any operating system: <strong>don't use
system Python</strong>. The OS <strong>relies</strong> on that Python, including the packages
(and package versions) it has installed. This means if it is modified in a
non-official way by you, then the OS may not have something it depends on.</p>
<p>For Mac OS X, system Python is installed in</p>
<div class=highlight><pre><span></span><code>/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python
</code></pre></div>
<p>(YMMV, this is on a "current"-ish OS X 10.11.6). You couldn't edit it if
you wanted to — not even with <code>sudo</code> — it's <a href="https://support.apple.com/en-us/HT204899">restricted</a>.</p>
<p>Instead, most choose one of</p>
<ul>
<li>the <a href="https://github.com/pyenv/pyenv">pyenv</a> version manager</li>
<li>a custom Python from <a href="https://brew.sh">Homebrew</a></li>
<li>the <a href="https://conda.io/docs/user-guide/install/macos.html">conda</a> package management system</li>
<li>"official" Python directly from <a href="https://www.python.org/downloads/mac-osx/">Python.org</a></li>
</ul>
<h3>What To Do</h3>
<p>I <strong>strongly</strong> recommend using <code>pyenv</code>. Once installed and configured it
allows easy switching between versions and more importantly allows you
to have all versions owned by you (not <code>root</code>) and in one easy to find
(and easy to remove) place.</p>
<p>For example, the system Python is <code>2.7.10</code> and was compiled with LLVM 7.0.0:</p>
<div class=highlight><pre><span></span><code><span class=err>$</span> <span class=o>/</span><span class=n>System</span><span class=o>/</span><span class=n>Library</span><span class=o>/</span><span class=n>Frameworks</span><span class=o>/</span><span class=n>Python</span><span class=o>.</span><span class=n>framework</span><span class=o>/</span><span class=n>Versions</span><span class=o>/</span><span class=mf>2.7</span><span class=o>/</span><span class=nb>bin</span><span class=o>/</span><span class=n>python2</span><span class=mf>.7</span> <span class=o>-</span><span class=n>c</span> \
<span class=o>></span> <span class=s1>'import sys; print(sys.version)'</span>
<span class=mf>2.7.10</span> <span class=p>(</span><span class=n>default</span><span class=p>,</span> <span class=n>Oct</span> <span class=mi>23</span> <span class=mi>2015</span><span class=p>,</span> <span class=mi>19</span><span class=p>:</span><span class=mi>19</span><span class=p>:</span><span class=mi>21</span><span class=p>)</span>
<span class=p>[</span><span class=n>GCC</span> <span class=mf>4.2.1</span> <span class=n>Compatible</span> <span class=n>Apple</span> <span class=n>LLVM</span> <span class=mf>7.0.0</span> <span class=p>(</span><span class=n>clang</span><span class=o>-</span><span class=mf>700.0.59.5</span><span class=p>)]</span>
</code></pre></div>
<p>However, with <code>pyenv</code> installed, we can use the latest<sup id=sf-python-on-os-x-1-back><a href=#sf-python-on-os-x-1 class=simple-footnote title="2.7.14 came out only a few days before this post">1</a></sup> version of 2.7<sup id=sf-python-on-os-x-2-back><a href=#sf-python-on-os-x-2 class=simple-footnote title="I would like to encourage you to use Python 3, and am just using 2.7 here because that is the system Python">2</a></sup>:</p>
<div class=highlight><pre><span></span><code><span class=err>$</span> <span class=n>python2</span><span class=mf>.7</span>
<span class=n>Python</span> <span class=mf>2.7.14</span> <span class=p>(</span><span class=n>default</span><span class=p>,</span> <span class=n>Sep</span> <span class=mi>19</span> <span class=mi>2017</span><span class=p>,</span> <span class=mi>20</span><span class=p>:</span><span class=mi>32</span><span class=p>:</span><span class=mi>14</span><span class=p>)</span>
<span class=p>[</span><span class=n>GCC</span> <span class=mf>4.2.1</span> <span class=n>Compatible</span> <span class=n>Apple</span> <span class=n>LLVM</span> <span class=mf>8.0.0</span> <span class=p>(</span><span class=n>clang</span><span class=o>-</span><span class=mf>800.0.42.1</span><span class=p>)]</span> <span class=n>on</span> <span class=n>darwin</span>
<span class=n>Type</span> <span class=s2>"help"</span><span class=p>,</span> <span class=s2>"copyright"</span><span class=p>,</span> <span class=s2>"credits"</span> <span class=ow>or</span> <span class=s2>"license"</span> <span class=k>for</span> <span class=n>more</span> <span class=n>information</span><span class=o>.</span>
<span class=o>>>></span> <span class=kn>import</span> <span class=nn>sys</span>
<span class=o>>>></span> <span class=n>sys</span><span class=o>.</span><span class=n>executable</span>
<span class=s1>'$</span><span class=si>{HOME}</span><span class=s1>/.pyenv/versions/2.7.14/bin/python'</span>
</code></pre></div>
<p>Multiple Python executables live peacefully together:</p>
<div class=highlight><pre><span></span><code><span class=err>$</span> <span class=n>python</span> <span class=o>-</span><span class=n>c</span> <span class=s1>'import sys; print(sys.executable)'</span>
<span class=err>$</span><span class=p>{</span><span class=n>HOME</span><span class=p>}</span><span class=o>/.</span><span class=n>pyenv</span><span class=o>/</span><span class=n>versions</span><span class=o>/</span><span class=mf>3.6.2</span><span class=o>/</span><span class=nb>bin</span><span class=o>/</span><span class=n>python</span>
<span class=err>$</span> <span class=n>python3</span><span class=mf>.5</span> <span class=o>-</span><span class=n>c</span> <span class=s1>'import sys; print(sys.executable)'</span>
<span class=err>$</span><span class=p>{</span><span class=n>HOME</span><span class=p>}</span><span class=o>/.</span><span class=n>pyenv</span><span class=o>/</span><span class=n>versions</span><span class=o>/</span><span class=mf>3.5.4</span><span class=o>/</span><span class=nb>bin</span><span class=o>/</span><span class=n>python3</span><span class=mf>.5</span>
</code></pre></div>
<p>When compared with the ease of <code>pyenv install ${VERSION}</code> without any root
privileges, downloading a <code>.pkg</code> from Python.org and running as administrator
seems unnecessary. However, I recently found a reason why the "official"
OS X Python binaries are worth having.</p>
<h3>Spinning Wheels</h3>
<p>I decided I should be a "good citizen" and provide built Python
wheels for a <a href="https://pypi.org/project/bezier/0.5.0/">package</a> of mine. Along the process, I came across
<a href="http://matthew.dynevor.org">Matthew Brett</a>'s wonderful <a href="https://github.com/MacPython/wiki/wiki/Spinning-wheels">Spinning Wheels</a>.</p>
<p>TL;DR: it's best to build wheels that target OS X with the Python
executables from Python.org.</p>
<p>The primary difference between a <code>pyenv</code> installed Python and an official
one can be seen in the platform tag:</p>
<div class=highlight><pre><span></span><code><span class=err>$</span> <span class=n>cat</span> <span class=n>get_platform</span><span class=o>.</span><span class=n>py</span>
<span class=kn>import</span> <span class=nn>distutils.util</span>
<span class=nb>print</span><span class=p>(</span><span class=n>distutils</span><span class=o>.</span><span class=n>util</span><span class=o>.</span><span class=n>get_platform</span><span class=p>())</span>
<span class=err>$</span> <span class=err>$</span><span class=p>{</span><span class=n>HOME</span><span class=p>}</span><span class=o>/.</span><span class=n>pyenv</span><span class=o>/</span><span class=n>versions</span><span class=o>/</span><span class=mf>3.6.2</span><span class=o>/</span><span class=nb>bin</span><span class=o>/</span><span class=n>python</span> <span class=n>get_platform</span><span class=o>.</span><span class=n>py</span>
<span class=n>macosx</span><span class=o>-</span><span class=mf>10.11</span><span class=o>-</span><span class=n>x86_64</span>
<span class=err>$</span> <span class=o>/</span><span class=n>Library</span><span class=o>/</span><span class=n>Frameworks</span><span class=o>/</span><span class=n>Python</span><span class=o>.</span><span class=n>framework</span><span class=o>/</span><span class=n>Versions</span><span class=o>/</span><span class=mf>3.6</span><span class=o>/</span><span class=nb>bin</span><span class=o>/</span><span class=n>python3</span> <span class=n>get_platform</span><span class=o>.</span><span class=n>py</span>
<span class=n>macosx</span><span class=o>-</span><span class=mf>10.6</span><span class=o>-</span><span class=n>intel</span>
</code></pre></div>
<p>First, the Python.org Python<sup id=sf-python-on-os-x-3-back><a href=#sf-python-on-os-x-3 class=simple-footnote title="The one that starts with /Library/...">3</a></sup>
supports an older SDK (10.6) which gives <strong>forward compatibility</strong> of any
binaries produced for any SDK after 10.6.</p>
<p>Second, the <code>intel</code> architecture means the executable is a <a href="https://en.wikipedia.org/wiki/Universal_binary">universal</a>
(or "fat") binary. This means it can support both <a href="https://docs.python.org/3/library/platform.html#cross-platform">32-bit</a> and 64-bit
architectures:</p>
<div class=highlight><pre><span></span><code><span class=err>$</span> <span class=n>cd</span> <span class=o>/</span><span class=n>Library</span><span class=o>/</span><span class=n>Frameworks</span><span class=o>/</span><span class=n>Python</span><span class=o>.</span><span class=n>framework</span><span class=o>/</span><span class=n>Versions</span><span class=o>/</span><span class=mf>3.6</span><span class=o>/</span><span class=nb>bin</span><span class=o>/</span>
<span class=err>$</span> <span class=o>./</span><span class=n>python3</span>
<span class=o>>>></span> <span class=kn>import</span> <span class=nn>sys</span>
<span class=o>>>></span> <span class=n>sys</span><span class=o>.</span><span class=n>maxsize</span>
<span class=mi>9223372036854775807</span>
<span class=o>>>></span> <span class=n>sys</span><span class=o>.</span><span class=n>maxsize</span> <span class=o>==</span> <span class=mi>2</span><span class=o>**</span><span class=p>(</span><span class=mi>64</span> <span class=o>-</span> <span class=mi>1</span><span class=p>)</span> <span class=o>-</span> <span class=mi>1</span>
<span class=kc>True</span>
<span class=err>$</span>
<span class=err>$</span> <span class=c1># OR arch -32</span>
<span class=err>$</span> <span class=n>arch</span> <span class=o>-</span><span class=n>i386</span> <span class=o>./</span><span class=n>python3</span> <span class=o>-</span><span class=n>c</span> <span class=s1>'import sys; print(sys.maxsize == 2**(32 - 1) - 1)'</span>
<span class=kc>True</span>
<span class=err>$</span> <span class=c1># OR arch -64</span>
<span class=err>$</span> <span class=n>arch</span> <span class=o>-</span><span class=n>x86_64</span> <span class=o>./</span><span class=n>python3</span> <span class=o>-</span><span class=n>c</span> <span class=s1>'import sys; print(sys.maxsize == 2**(64 - 1) - 1)'</span>
<span class=kc>True</span>
</code></pre></div>
<h3><code>pyenv</code> with official Python</h3>
<p>To get the best of both worlds and use the official Python.org binaries
from <code>pyenv</code>:</p>
<ul>
<li><a href="https://www.python.org/downloads/mac-osx/">Download</a> the <code>.pkg</code> installers for Python 2.7, 3.5, 3.6 and
any other version you wish to support.</li>
<li>Install each of the <code>.pkg</code> files (this will require administrator
privileges, sorry). These will be installed into
<code>/Library/Frameworks/Python.framework/Versions/X.Y</code>.</li>
<li>Reset your <code>${HOME}/.bash_profile</code>. The Python.org installers will
have each added a line to your <code>bash</code> profile that puts
<code>/Library/Frameworks/Python.framework/Versions/X.Y/bin</code> at
the beginning of your <code>${PATH}</code>. This will "jump in line" in front
of <code>pyenv</code>, which is not what we want.</li>
<li>(Optional) Add a <code>python</code> executable for the installed Python 3 versions
(they don't come with <code>python</code>, see <a href="https://www.python.org/dev/peps/pep-0394/">PEP 394</a>).</li>
</ul>
<div class=highlight><pre><span></span><code>$ <span class=o>(</span><span class=nb>cd</span> /Library/Frameworks/Python.framework/Versions/3.5/bin/ <span class=o>&&</span> <span class=se>\</span>
> ln -s python3 python<span class=o>)</span>
$ <span class=o>(</span><span class=nb>cd</span> /Library/Frameworks/Python.framework/Versions/3.6/bin/ <span class=o>&&</span> <span class=se>\</span>
> ln -s python3 python<span class=o>)</span>
</code></pre></div>
<ul>
<li>Convince <code>pyenv</code> that these are installed versions:</li>
</ul>
<div class=highlight><pre><span></span><code>$ ln -s /Library/Frameworks/Python.framework/Versions/2.7 <span class=se>\</span>
> <span class=si>${</span><span class=nv>HOME</span><span class=si>}</span>/.pyenv/versions/python-dot-org-2.7
$ ln -s /Library/Frameworks/Python.framework/Versions/3.5 <span class=se>\</span>
> <span class=si>${</span><span class=nv>HOME</span><span class=si>}</span>/.pyenv/versions/python-dot-org-3.5
$ ln -s /Library/Frameworks/Python.framework/Versions/3.6 <span class=se>\</span>
> <span class=si>${</span><span class=nv>HOME</span><span class=si>}</span>/.pyenv/versions/python-dot-org-3.6
</code></pre></div>
<ul>
<li>(Optional) Un-confuse <code>pyenv</code> about what the <strong>actual</strong> system Python is:</li>
</ul>
<div class=highlight><pre><span></span><code>$ ln -s /System/Library/Frameworks/Python.framework/Versions/2.7 <span class=se>\</span>
> <span class=si>${</span><span class=nv>HOME</span><span class=si>}</span>/.pyenv/versions/system-2.7
</code></pre></div>
<ul>
<li>Execute <code>pyenv rehash</code> so the binaries in the new versions get
registered with <code>pyenv</code>.</li>
</ul>
<p>Once done:</p>
<div class=highlight><pre><span></span><code>$ pyenv versions
system
* <span class=m>2</span>.7.14 <span class=o>(</span><span class=nb>set</span> by <span class=si>${</span><span class=nv>HOME</span><span class=si>}</span>/.pyenv/version<span class=o>)</span>
* <span class=m>3</span>.5.4 <span class=o>(</span><span class=nb>set</span> by <span class=si>${</span><span class=nv>HOME</span><span class=si>}</span>/.pyenv/version<span class=o>)</span>
* <span class=m>3</span>.6.2 <span class=o>(</span><span class=nb>set</span> by <span class=si>${</span><span class=nv>HOME</span><span class=si>}</span>/.pyenv/version<span class=o>)</span>
* pypy2.7-5.8.0 <span class=o>(</span><span class=nb>set</span> by <span class=si>${</span><span class=nv>HOME</span><span class=si>}</span>/.pyenv/version<span class=o>)</span>
python-dot-org-2.7
python-dot-org-3.5
python-dot-org-3.6
system-2.7
</code></pre></div><ol class=simple-footnotes><li id=sf-python-on-os-x-1>2.7.14 came out
only a few days before this post <a href=#sf-python-on-os-x-1-back class=simple-footnote-back>↩</a></li><li id=sf-python-on-os-x-2>I would like
to <a href="https://pythonclock.org">encourage</a> you to use Python 3, and am just using 2.7 here
because that is the system Python <a href=#sf-python-on-os-x-2-back class=simple-footnote-back>↩</a></li><li id=sf-python-on-os-x-3>The one that starts with <code>/Library/...</code> <a href=#sf-python-on-os-x-3-back class=simple-footnote-back>↩</a></li></ol>How Does Go Compute a Logarithm2017-02-06T00:00:00-08:002017-02-06T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2017-02-06:/2017/02/golang-and-log-x.html<p>About a year ago, I was reading the Go <a href="https://golang.org/src/math/log.go">source</a> for computing
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>log</mi><mo></mo><mo stretchy=false>(</mo><mi>x</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">\log(x)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mclose>)</span></span></span></span> and was very surprised by the
implementation.<sup id=sf-golang-and-log-x-1-back><a href=#sf-golang-and-log-x-1 class=simple-footnote title="Why would anyone look in this source? I was trying to explain to a student that a computer would compute this with minimal error when I realized I didn't know how.">1</a></sup></p>
<p>Even three years into a PhD in Applied Math (i.e. numerics), I still
managed to learn something by diving in and trying …</p><p>About a year ago, I was reading the Go <a href="https://golang.org/src/math/log.go">source</a> for computing
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>log</mi><mo></mo><mo stretchy=false>(</mo><mi>x</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">\log(x)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mclose>)</span></span></span></span> and was very surprised by the
implementation.<sup id=sf-golang-and-log-x-1-back><a href=#sf-golang-and-log-x-1 class=simple-footnote title="Why would anyone look in this source? I was trying to explain to a student that a computer would compute this with minimal error when I realized I didn't know how.">1</a></sup></p>
<p>Even three years into a PhD in Applied Math (i.e. numerics), I still
managed to learn something by diving in and trying to understand what
was going on.</p>
<h3>(Almost-)Correctness</h3>
<p>Really I just wanted a chance to share a neat error plot:</p>
<div style="text-align: center;">
<p><img alt="Equioscillating Error" src="/images/remez_equioscillating_error.png"></p>
</div>
<p>The high-level:</p>
<ul>
<li>The computation <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>log</mi><mo></mo><mo stretchy=false>(</mo><mi>x</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">\log(x)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mclose>)</span></span></span></span> can be
reduced to computing a related function <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">R(s)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span></span></span></span>
(where the value <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi></mrow><annotation encoding="application/x-tex">s</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">s</span></span></span></span> can be obtained from
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">x</span></span></span></span> on a computer in some straightforward way)</li>
<li><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">R(s)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span></span></span></span> can be approximated by a function that
we can actually compute with simple floating point operations:
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">f(s)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.10764em;>f</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span></span></span></span></li>
<li>The error <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo><mo>−</mo><mi>f</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">R(s) - f(s)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.10764em;>f</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span></span></span></span> is <a href="https://en.wikipedia.org/wiki/Equioscillation_theorem">"equioscillating"</a>,
i.e. it minimizes the maximum error, a so-called
<a href="https://en.wikipedia.org/wiki/Minimax_approximation_algorithm">minimax</a> solution</li>
</ul>
<p>If you're still interested in some mathematical details, stick
around. If not, I hope you enjoyed the pretty picture.</p>
<h3>Doing the Obvious</h3>
<p>The "obvious" idea that comes to mind is to use a <a href="https://en.wikipedia.org/wiki/Taylor_series">Taylor series</a>
approximation. But <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>log</mi><mo></mo><mo stretchy=false>(</mo><mi>x</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">\log(x)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mclose>)</span></span></span></span> is not defined at
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>=</mo><mn>0</mn><mo separator=true>,</mo></mrow><annotation encoding="application/x-tex">x = 0,</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.8388800000000001em;vertical-align:-0.19444em;></span><span class=mord>0</span><span class=mpunct>,</span></span></span></span> so a Taylor series of a related function is
typically used<sup id=sf-golang-and-log-x-2-back><a href=#sf-golang-and-log-x-2 class=simple-footnote title='This series is typically learned and forgotten by those who have made it through "Calc II".'>2</a></sup>:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>log</mi><mo></mo><mrow><mo fence=true>(</mo><mn>1</mn><mo>+</mo><mi>x</mi><mo fence=true>)</mo></mrow><mo>=</mo><mi>x</mi><mo>−</mo><mfrac><msup><mi>x</mi><mn>2</mn></msup><mn>2</mn></mfrac><mo>+</mo><mfrac><msup><mi>x</mi><mn>3</mn></msup><mn>3</mn></mfrac><mo>−</mo><mfrac><msup><mi>x</mi><mn>4</mn></msup><mn>4</mn></mfrac><mo>+</mo><mo>⋯</mo></mrow><annotation encoding="application/x-tex">\log\left(1 + x\right) = x - \frac{x^2}{2} + \frac{x^3}{3} - \frac{x^4}{4} + \cdots</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">x</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.66666em;vertical-align:-0.08333em;></span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.177108em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.491108em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">x</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.177108em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.491108em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">x</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.177108em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.491108em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>4</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord><span class="mord mathnormal">x</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141079999999999em;><span style=top:-3.063em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.313em;vertical-align:0em;></span><span class=minner>⋯</span></span></span></span></span>
</blockquote></div>
<p>But, the implementation doesn't do the obvious thing. Instead
it breaks down the argument into an exponent and a fractional part</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>x</mi><mo>=</mo><msup><mn>2</mn><mi>k</mi></msup><mrow><mo fence=true>(</mo><mfrac><mrow><mn>1</mn><mo>+</mo><mi>s</mi></mrow><mrow><mn>1</mn><mo>−</mo><mi>s</mi></mrow></mfrac><mo fence=true>)</mo></mrow></mrow><annotation encoding="application/x-tex">x = 2^k \left(\frac{1 + s}{1 - s}\right)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.43056em;vertical-align:0em;></span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.40003em;vertical-align:-0.95003em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8991079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style=margin-right:0.03148em;>k</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;><span class="delimsizing size3">(</span></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">s</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">s</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.7693300000000001em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style=top:0em;><span class="delimsizing size3">)</span></span></span></span></span></span></span>
</blockquote></div>
<p>which transforms the computation to:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>log</mi><mo></mo><mo stretchy=false>(</mo><mi>x</mi><mo stretchy=false>)</mo><mo>=</mo><mi>k</mi><mi>log</mi><mo></mo><mo stretchy=false>(</mo><mn>2</mn><mo stretchy=false>)</mo><mo>+</mo><mrow><mo fence=true>[</mo><mi>log</mi><mo></mo><mrow><mo fence=true>(</mo><mn>1</mn><mo>+</mo><mi>s</mi><mo fence=true>)</mo></mrow><mo>−</mo><mi>log</mi><mo></mo><mrow><mo fence=true>(</mo><mn>1</mn><mo>−</mo><mi>s</mi><mo fence=true>)</mo></mrow><mo fence=true>]</mo></mrow><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">\log(x) = k \log(2) + \left[\log\left(1 + s\right) - \log\left(1 - s\right)\right].</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.03148em;>k</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mopen>(</span><span class=mord>2</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>[</span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">s</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">s</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class="mclose delimcenter" style=top:0em;>]</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<p>The first part <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mi>log</mi><mo></mo><mo stretchy=false>(</mo><mn>2</mn><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">k \log(2)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.03148em;>k</span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mopen>(</span><span class=mord>2</span><span class=mclose>)</span></span></span></span> can be handled in maximal
precision for the limited set of integer values that <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.69444em;vertical-align:0em;></span><span class="mord mathnormal" style=margin-right:0.03148em;>k</span></span></span></span>
can be.</p>
<h3>Finding a Function to Approximate</h3>
<p>For the other part</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mtable rowspacing=0.2500em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mi>log</mi><mo></mo><mrow><mo fence=true>(</mo><mn>1</mn><mo>+</mo><mi>s</mi><mo fence=true>)</mo></mrow><mo>−</mo><mi>log</mi><mo></mo><mrow><mo fence=true>(</mo><mn>1</mn><mo>−</mo><mi>s</mi><mo fence=true>)</mo></mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mn>2</mn><mi>s</mi><mo>+</mo><mfrac><mn>2</mn><mn>3</mn></mfrac><msup><mi>s</mi><mn>3</mn></msup><mo>+</mo><mfrac><mn>2</mn><mn>5</mn></mfrac><msup><mi>s</mi><mn>5</mn></msup><mo>+</mo><mo>⋯</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow></mrow><mo>=</mo><mn>2</mn><mi>s</mi><mo>+</mo><mi>s</mi><mi>R</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo><mi mathvariant=normal>.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}\log\left(1 + s\right) - \log\left(1 - s\right) &= 2 s + \frac{2}{3} s^3 + \frac{2}{5} s^5 + \cdots \\ &= 2 s + s R(s). \end{aligned}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:3.8074400000000006em;vertical-align:-1.6537200000000003em;></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.1537200000000003em;><span style=top:-4.15372em;><span class=pstrut style=height:3.32144em;></span><span class=mord><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">s</span><span class="mclose delimcenter" style=top:0em;>)</span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mop>lo<span style=margin-right:0.01389em;>g</span></span><span class=mspace style=margin-right:0.16666666666666666em;></span><span class=minner><span class="mopen delimcenter" style=top:0em;>(</span><span class=mord>1</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">s</span><span class="mclose delimcenter" style=top:0em;>)</span></span></span></span><span style=top:-2.32772em;><span class=pstrut style=height:3.32144em;></span><span class=mord></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.6537200000000003em;><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.1537200000000003em;><span style=top:-4.15372em;><span class=pstrut style=height:3.32144em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>2</span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>5</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=minner>⋯</span></span></span><span style=top:-2.32772em;><span class=pstrut style=height:3.32144em;></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mord>2</span><span class="mord mathnormal">s</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class="mord mathnormal">s</span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span><span class=mord>.</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.6537200000000003em;><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>From here, I expected a polynomial approximation that just takes the first
few terms in <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">R(s)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span></span></span></span>.
However, coefficients that are close (but not equal) are given:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>R</mi><mo stretchy=false>(</mo><mi>z</mi><mo stretchy=false>)</mo><mo>≈</mo><msub><mi>L</mi><mn>1</mn></msub><msup><mi>s</mi><mn>2</mn></msup><mo>+</mo><msub><mi>L</mi><mn>2</mn></msub><msup><mi>s</mi><mn>4</mn></msup><mo>+</mo><mo>⋯</mo><mo>+</mo><msub><mi>L</mi><mn>6</mn></msub><msup><mi>s</mi><mn>12</mn></msup><mo>+</mo><msub><mi>L</mi><mn>7</mn></msub><msup><mi>s</mi><mn>14</mn></msup></mrow><annotation encoding="application/x-tex">R(z) \approx L_1 s^2 + L_2 s^4 + \cdots + L_6 s^{12} + L_7 s^{14}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.04398em;>z</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≈</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:1.0141079999999998em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">L</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.0141079999999998em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">L</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.66666em;vertical-align:-0.08333em;></span><span class=minner>⋯</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.0141079999999998em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">L</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">12</span></span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:1.0141079999999998em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">L</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">7</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">14</span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<div class=highlight><pre><span></span><code>L1 = 6.666666666666735130e-01 /* 3FE55555 55555593 */
L2 = 3.999999999940941908e-01 /* 3FD99999 9997FA04 */
L3 = 2.857142874366239149e-01 /* 3FD24924 94229359 */
L4 = 2.222219843214978396e-01 /* 3FCC71C5 1D8E78AF */
L5 = 1.818357216161805012e-01 /* 3FC74664 96CB03DE */
L6 = 1.531383769920937332e-01 /* 3FC39A09 D078C69F */
L7 = 1.479819860511658591e-01 /* 3FC2F112 DF3E5244 */
</code></pre></div>
<p>For example:</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><msub><mi>L</mi><mn>1</mn></msub><mo>=</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>1</mn></mrow></msup><mo>⋅</mo><mn>1.555555555559</mn><msub><mn>3</mn><mn>16</mn></msub><mo>=</mo><mfrac><mn>2</mn><mn>3</mn></mfrac><mo>+</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>53</mn></mrow></msup><mo>⋅</mo><mfrac><mn>185</mn><mn>3</mn></mfrac><mo>≈</mo><mfrac><mn>2</mn><mn>3</mn></mfrac><mi mathvariant=normal>.</mi></mrow><annotation encoding="application/x-tex">L_1 = 2^{-1} \cdot 1.5555555555593_{16} = \frac{2}{3} + 2^{-53} \cdot \frac{185}{3} \approx \frac{2}{3}.</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.83333em;vertical-align:-0.15em;></span><span class=mord><span class="mord mathnormal">L</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:0.864108em;vertical-align:0em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.864108em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.79444em;vertical-align:-0.15em;></span><span class=mord>1.555555555559</span><span class=mord><span class=mord>3</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.30110799999999993em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">16</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em;><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.864108em;vertical-align:0em;></span><span class=mord><span class=mord>2</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.864108em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">53</span></span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>⋅</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>185</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≈</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord>.</span></span></span></span></span>
</blockquote></div>
<h3>Not Go, Sun</h3>
<p>You may have noted my typo above: I used <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo stretchy=false>(</mo><mi>z</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">R(z)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal" style=margin-right:0.04398em;>z</span><span class=mclose>)</span></span></span></span>
when I should've used <span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo></mrow><annotation encoding="application/x-tex">R(s)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span></span></span></span>. This typo is
directly from the source; not my copy-paste error, but a
copy-paste error in the original source.</p>
<p>The original authors aren't the Golang devs:</p>
<div class=highlight><pre><span></span><code><span class=o>//</span> <span class=n>The</span> <span class=n>original</span> <span class=n>C</span> <span class=n>code</span><span class=p>,</span> <span class=n>the</span> <span class=n>long</span> <span class=n>comment</span><span class=p>,</span> <span class=ow>and</span> <span class=n>the</span> <span class=n>constants</span>
<span class=o>//</span> <span class=n>below</span> <span class=n>are</span> <span class=n>from</span> <span class=n>FreeBSD</span><span class=s1>'s /usr/src/lib/msun/src/e_log.c</span>
<span class=o>//</span> <span class=ow>and</span> <span class=n>came</span> <span class=n>with</span> <span class=n>this</span> <span class=n>notice</span><span class=o>.</span> <span class=n>The</span> <span class=n>go</span> <span class=n>code</span> <span class=k>is</span> <span class=n>a</span> <span class=n>simpler</span>
<span class=o>//</span> <span class=n>version</span> <span class=n>of</span> <span class=n>the</span> <span class=n>original</span> <span class=n>C</span><span class=o>.</span>
</code></pre></div>
<p>It seems they copied <strong>everything</strong>, even the typos. Another
typo can be found when the description mentions
"a special Reme algorithm" used to compute the coefficients
<span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>L</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">L_j</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.969438em;vertical-align:-0.286108em;></span><span class=mord><span class="mord mathnormal">L</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.311664em;><span style=top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style=margin-right:0.05724em;>j</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.286108em;><span></span></span></span></span></span></span></span></span></span>.</p>
<p>This typo is a bit more egregious: it actually uses a
<a href="https://en.wikipedia.org/wiki/Remez_algorithm"><strong>Remez</strong> algorithm</a>.</p>
<h3>Remez Algorithm</h3>
<p>This algorithm takes a polynomial approximation like</p>
<div class=katex-elt><blockquote>
<span class=katex-display><span class=katex><span class=katex-mathml><math xmlns="http://www.w3.org/1998/Math/MathML" display=block><semantics><mrow><mi>R</mi><mo stretchy=false>(</mo><mi>s</mi><mo stretchy=false>)</mo><mo>≈</mo><mfrac><mn>2</mn><mn>3</mn></mfrac><msup><mi>s</mi><mn>2</mn></msup><mo>+</mo><mfrac><mn>2</mn><mn>5</mn></mfrac><msup><mi>s</mi><mn>4</mn></msup><mo>+</mo><mo>⋯</mo><mo>+</mo><mfrac><mn>2</mn><mn>15</mn></mfrac><msup><mi>s</mi><mn>14</mn></msup></mrow><annotation encoding="application/x-tex">R(s) \approx \frac{2}{3} s^2 + \frac{2}{5} s^4 + \cdots + \frac{2}{15} s^{14}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em;></span><span class="mord mathnormal" style=margin-right:0.00773em;>R</span><span class=mopen>(</span><span class="mord mathnormal">s</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2777777777777778em;></span><span class=mrel>≈</span><span class=mspace style=margin-right:0.2777777777777778em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>3</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>5</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:0.66666em;vertical-align:-0.08333em;></span><span class=minner>⋯</span><span class=mspace style=margin-right:0.2222222222222222em;></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222222222222222em;></span></span><span class=base><span class=strut style=height:2.00744em;vertical-align:-0.686em;></span><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.32144em;><span style=top:-2.314em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>15</span></span></span><span style=top:-3.23em;><span class=pstrut style=height:3em;></span><span class=frac-line style=border-bottom-width:0.04em;></span></span><span style=top:-3.677em;><span class=pstrut style=height:3em;></span><span class=mord><span class=mord>2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em;><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class=mord><span class="mord mathnormal">s</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8641079999999999em;><span style=top:-3.113em;margin-right:0.05em;><span class=pstrut style=height:2.7em;></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">14</span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>and systematically modifies the coefficients until the error is
<a href="https://en.wikipedia.org/wiki/Equioscillation_theorem">"equioscillating"</a>:</p>
<div style="text-align: center;">
<p><img alt="Equioscillating Error" src="/images/remez_equioscillating_error.png"></p>
</div>
<h3>Is That All You've Got?</h3>
<p>I hope to follow this post up with <a href="https://gist.github.com/dhermes/105da2a3c9861c90ea39">some code</a> to actually compute
the coefficients that give an equioscillating error (and to show some
coefficients that do slightly better).</p><ol class=simple-footnotes><li id=sf-golang-and-log-x-1>Why would anyone look in this source? I was
trying to explain to a student that a computer would compute
this with minimal error when I realized I didn't know <strong>how</strong>. <a href=#sf-golang-and-log-x-1-back class=simple-footnote-back>↩</a></li><li id=sf-golang-and-log-x-2>This series is typically learned and forgotten by
those who have made it through "Calc II". <a href=#sf-golang-and-log-x-2-back class=simple-footnote-back>↩</a></li></ol>Newton's (Method's) Failure2016-11-24T00:00:00-08:002016-11-24T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2016-11-24:/2016/11/newtons-failure.html<p>Finding zeros of any old function is a common task, and using
<a href="https://en.wikipedia.org/wiki/Newton's_method">Newton's method</a> is one of the best tools for carrying
out this task. I've even <a href="/2012/05/reverse-calculating-interest-rate.html">written</a> an old post that used this
method.</p>
<p>However, Newton's method loses some of it's luster around
repeated roots. Consider the iteration</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>x …</mi></msub></mrow></semantics></math></span></span></span></blockquote></div><p>Finding zeros of any old function is a common task, and using
<a href="https://en.wikipedia.org/wiki/Newton's_method">Newton's method</a> is one of the best tools for carrying
out this task. I've even <a href="/2012/05/reverse-calculating-interest-rate.html">written</a> an old post that used this
method.</p>
<p>However, Newton's method loses some of it's luster around
repeated roots. Consider the iteration</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>x</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mi>x</mi><mi>n</mi></msub><mo>−</mo><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">)</mo></mrow><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">x_{n + 1} = x_n - \frac{f(x_n)}{f'(x_n)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6778919999999999em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>On inspection, points where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">)</mo><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">f'(x_n) = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> seem to be
problematic. However, when these points are also roots, the division
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn><mi mathvariant="normal">/</mi><mn>0</mn></mrow><annotation encoding="application/x-tex">0 / 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0/0</span></span></span></span> may no longer be a problem. The case where</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">)</mo><mo>=</mo><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msub><mi>x</mi><mi>n</mi></msub><mo stretchy="false">)</mo><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">f(x_n) = f'(x_n) = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span></span>
</blockquote></div>
<p>is <strong>exactly</strong> the case of a repeated root.</p>
<p>For a practical example, consider <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">f(x) = (x - 1)^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>
which has corresponding iteration function</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>x</mi><mo>−</mo><mfrac><mrow><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow><mrow><mn>2</mn><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></mfrac><mo>=</mo><mfrac><mrow><mi>x</mi><mo>+</mo><mn>1</mn></mrow><mn>2</mn></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">g(x) = x - \frac{(x - 1)^2}{2(x - 1)} = \frac{x + 1}{2}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.427108em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.491108em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Starting with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mn>0</mn></msub><mo>=</mo><mn>1</mn><mo>+</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>0</mn></mrow></msup><mo>=</mo><mn>2</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">x_0 = 1 + 2^{-0} = 2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">0</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">2</span><span class="mpunct">,</span></span></span></span> in exact
arithmetic (i.e. no rounding) we'll always have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mi>n</mi></msub><mo>=</mo><mn>1</mn><mo>+</mo><msup><mn>2</mn><mrow><mo>−</mo><mi>n</mi></mrow></msup></mrow><annotation encoding="application/x-tex">x_n = 1 + 2^{-n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.771331em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span> since</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><mrow><mn>1</mn><mo>+</mo><msub><mi>x</mi><mi>n</mi></msub></mrow><mn>2</mn></mfrac><mo>=</mo><mfrac><mrow><mn>2</mn><mo>+</mo><msup><mn>2</mn><mrow><mo>−</mo><mi>n</mi></mrow></msup></mrow><mn>2</mn></mfrac><mo>=</mo><mn>1</mn><mo>+</mo><msup><mn>2</mn><mrow><mo>−</mo><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msup><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\frac{1 + x_n}{2} = \frac{2 + 2^{-n}}{2} = 1 + 2^{-n-1}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.134331em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.448331em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.864108em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>This sequence converges to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and
the error halves every term. However, in <a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format">double precision</a>, the
sequence stops once <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>53</mn></mrow><annotation encoding="application/x-tex">n = 53</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">53</span></span></span></span>: at that
point <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>⊕</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>53</mn></mrow></msup><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">1 \oplus 2^{-53} = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">53</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>.</p>
<p>However, if we told the computer that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f(x) = (x - 1)^2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span>
there would be no reason to use Newton's method, the roots are clearly
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>. Instead, the "data"
the computer is given are the coefficients in
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><mn>2</mn><mi>x</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">x^2 - 2x + 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and each term is
computed in floating point</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>x</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mi>x</mi><mi>n</mi></msub><mo>⊖</mo><mrow><mo fence="true">(</mo><msub><mi>N</mi><mi>n</mi></msub><mo>⊘</mo><msub><mi>D</mi><mi>n</mi></msub><mo fence="true">)</mo></mrow><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">x_{n + 1} = x_n \ominus \left(N_n \oslash D_n\right).</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊖</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.10903em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊘</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02778em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>where the numerator and denominator are given
(with the help of <a href="https://en.wikipedia.org/wiki/Horner's_method">Horner's method</a>) by</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>N</mi><mi>n</mi></msub><mo>=</mo><mrow><mo fence="true">(</mo><mo stretchy="false">(</mo><msub><mi>x</mi><mi>n</mi></msub><mo>⊖</mo><mn>2</mn><mo stretchy="false">)</mo><mo>⊗</mo><msub><mi>x</mi><mi>n</mi></msub><mo fence="true">)</mo></mrow><mo>⊕</mo><mn>1</mn><mo separator="true">,</mo><mspace width="1em"/><msub><mi>D</mi><mi>n</mi></msub><mo>=</mo><mrow><mo fence="true">(</mo><mn>2</mn><mo>⊗</mo><msub><mi>x</mi><mi>n</mi></msub><mo fence="true">)</mo></mrow><mo>⊖</mo><mn>2.</mn></mrow><annotation encoding="application/x-tex">N_n = \left((x_n \ominus 2) \otimes x_n\right) \oplus 1, \quad D_n = \left(2 \otimes x_n\right) \ominus 2.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.10903em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊖</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">2</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.02778em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊖</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2.</span></span></span></span></span>
</blockquote></div>
<p>Each floating point operation
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mo>⊗</mo><mo separator="true">,</mo><mo>⊘</mo><mo separator="true">,</mo><mo>⊕</mo><mo separator="true">,</mo><mo>⊖</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(\otimes, \oslash, \oplus, \ominus)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">⊗</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">⊘</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">⊕</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">⊖</span><span class="mclose">)</span></span></span></span> rounds the
"exact" result to the nearest floating point number. For
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mn>1</mn></msub><mo separator="true">,</mo><mtext> </mtext><mo>…</mo><mo separator="true">,</mo><mtext> </mtext><msub><mi>x</mi><mn>27</mn></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">x_1, \, \ldots, \, x_{27},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">27</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> there is no rounding
needed and we get the same values that we got in exact
arithmetic.</p>
<p>The <strong>real problem</strong> happens when <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>27</mn></mrow><annotation encoding="application/x-tex">n = 27</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">27</span></span></span></span>. At that
point</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><msub><mi>x</mi><mi>n</mi></msub><mo>⊖</mo><mn>2</mn><mo stretchy="false">)</mo><mo>⊗</mo><msub><mi>x</mi><mi>n</mi></msub><mo>=</mo><mrow><mo fence="true">(</mo><mo>−</mo><mrow><mo fence="true">(</mo><mn>1</mn><mo>−</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>27</mn></mrow></msup><mo fence="true">)</mo></mrow><mo fence="true">)</mo></mrow><mo>⊗</mo><mrow><mo fence="true">(</mo><mn>1</mn><mo>+</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>27</mn></mrow></msup><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">(x_n \ominus 2) \otimes x_n = \left(-\left(1 - 2^{-27}\right)\right) \otimes \left(1 + 2^{-27}\right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊖</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.214118em;vertical-align:-0.35001em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord">−</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">27</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.214118em;vertical-align:-0.35001em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">27</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span></span>
</blockquote></div>
<p>and the exact result <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>−</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>54</mn></mrow></msup></mrow><annotation encoding="application/x-tex">1 - 2^{-54}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">54</span></span></span></span></span></span></span></span></span></span></span></span> needs to be
rounded into floating point:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>N</mi><mn>27</mn></msub><mo>=</mo><mrow><mo fence="true">(</mo><mo>−</mo><mo stretchy="false">(</mo><mn>1</mn><mo>⊖</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>54</mn></mrow></msup><mo stretchy="false">)</mo><mo fence="true">)</mo></mrow><mo>⊕</mo><mn>1</mn><mo>=</mo><mrow><mo fence="true">(</mo><mo>−</mo><mn>1</mn><mo fence="true">)</mo></mrow><mo>⊕</mo><mn>1</mn><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">N_{27} = \left(-(1 \ominus 2^{-54})\right) \oplus 1 = \left(-1\right) \oplus 1 = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.10903em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">27</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.214118em;vertical-align:-0.35001em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord">−</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊖</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">54</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">−</span><span class="mord">1</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊕</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span></span>
</blockquote></div>
<p>which forces <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mn>28</mn></msub><mo>=</mo><msub><mi>x</mi><mn>27</mn></msub><mo>⊖</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">x_{28} = x_{27} \ominus 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">28</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">27</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⊖</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>.
After this point, the iteration stalls and every term after is equal
to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mn>27</mn></msub></mrow><annotation encoding="application/x-tex">x_{27}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">27</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>.</p>
<p>Thus when the algorithm terminates on a computer (since two consecutive
terms are identical), the actual error is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mrow><mo>−</mo><mn>27</mn></mrow></msup></mrow><annotation encoding="application/x-tex">2^{-27}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">27</span></span></span></span></span></span></span></span></span></span></span></span>.
This error is <strong>much too large</strong>! Using the standard floating point
type (<code>double</code>), the <a href="https://en.wikipedia.org/wiki/Machine_epsilon">machine precision</a> is
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>ε</mi><mo>=</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>52</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\varepsilon = 2^{-52}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">ε</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">52</span></span></span></span></span></span></span></span></span></span></span></span> and our error is approximately
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>ε</mi></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{\varepsilon}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.23972em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8002800000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal">ε</span></span></span><span style="top:-2.76028em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.23972em;"><span></span></span></span></span></span></span></span></span>. In other words, we <strong>expected</strong>
52 bits of precision and <strong>only get</strong> 27!</p>
<hr />
<p>In general, a root repeated <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> times — i.e. with
<strong>multiplicity</strong> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> — will only be accurate to
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>52</mn><mi>m</mi></mfrac></mrow><annotation encoding="application/x-tex">\frac{52}{m}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">m</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">52</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> bits, a very large penalty!</p>
<p>We can see this phenomenon in action, we define the
following function to do one Newton step using Horner's
method:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">horner_newton</span><span class="p">(</span><span class="n">coeffs</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span>
<span class="n">degree</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">coeffs</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">deriv_factor</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">degree</span><span class="p">)</span>
<span class="n">fx</span> <span class="o">=</span> <span class="n">fpx</span> <span class="o">=</span> <span class="mf">0.0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">degree</span><span class="p">):</span>
<span class="n">fx</span> <span class="o">=</span> <span class="n">val</span> <span class="o">*</span> <span class="n">fx</span> <span class="o">+</span> <span class="n">coeffs</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="n">fpx</span> <span class="o">=</span> <span class="n">val</span> <span class="o">*</span> <span class="n">fpx</span> <span class="o">+</span> <span class="n">deriv_factor</span> <span class="o">*</span> <span class="n">coeffs</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="n">deriv_factor</span> <span class="o">-=</span> <span class="mf">1.0</span>
<span class="c1"># Add the last term to fx.</span>
<span class="n">fx</span> <span class="o">=</span> <span class="n">val</span> <span class="o">*</span> <span class="n">fx</span> <span class="o">+</span> <span class="n">coeffs</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">return</span> <span class="n">val</span> <span class="o">-</span> <span class="n">fx</span> <span class="o">/</span> <span class="n">fpx</span>
</code></pre></div>
<p>Applying it to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><mn>2</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><msup><mi>x</mi><mn>4</mn></msup><mo>−</mo><mn>4</mn><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">(x^2 - 2)^2 = x^4 - 4x^2 + 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span> — which
has two double roots — we get</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="n">values</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1.0</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">coeffs</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">next_val</span> <span class="o">=</span> <span class="n">horner_newton</span><span class="p">(</span><span class="n">coeffs</span><span class="p">,</span> <span class="n">values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="o">>>></span> <span class="k">while</span> <span class="n">next_val</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>
<span class="o">...</span> <span class="n">values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">next_val</span><span class="p">)</span>
<span class="o">...</span> <span class="n">next_val</span> <span class="o">=</span> <span class="n">horner_newton</span><span class="p">(</span><span class="n">coeffs</span><span class="p">,</span> <span class="n">values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="o">...</span>
<span class="o">>>></span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
<span class="mi">28</span>
<span class="o">>>></span> <span class="n">values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="mf">1.4142135634821</span>
<span class="o">>>></span> <span class="n">math</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span><span class="p">)),</span> <span class="mi">2</span><span class="p">)</span>
<span class="o">-</span><span class="mf">29.74808712981571</span>
</code></pre></div>
<p>i.e. the error is around
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mrow><mo>−</mo><mn>29</mn></mrow></msup><mo>≈</mo><msqrt><mi>ε</mi></msqrt></mrow><annotation encoding="application/x-tex">2^{-29} \approx \sqrt{\varepsilon}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">29</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.23972em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8002800000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal">ε</span></span></span><span style="top:-2.76028em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.23972em;"><span></span></span></span></span></span></span></span></span>.</p>
<p>Trying out with a triple root
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>3</mn></msup><mo>=</mo><msup><mi>x</mi><mn>3</mn></msup><mo>−</mo><mn>3</mn><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>3</mn><mi>x</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">(x - 1)^3 = x^3 - 3 x^2 + 3x - 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> we get</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="n">values</span> <span class="o">=</span> <span class="p">[</span><span class="mf">2.0</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">coeffs</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="o">>>></span> <span class="n">next_val</span> <span class="o">=</span> <span class="n">horner_newton</span><span class="p">(</span><span class="n">coeffs</span><span class="p">,</span> <span class="n">values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="o">>>></span> <span class="k">while</span> <span class="n">next_val</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>
<span class="o">...</span> <span class="n">values</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">next_val</span><span class="p">)</span>
<span class="o">...</span> <span class="n">next_val</span> <span class="o">=</span> <span class="n">horner_newton</span><span class="p">(</span><span class="n">coeffs</span><span class="p">,</span> <span class="n">values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="o">...</span>
<span class="o">>>></span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
<span class="mi">31</span>
<span class="o">>>></span> <span class="n">values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="mf">1.0000046685597561</span>
<span class="o">>>></span> <span class="n">math</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span>
<span class="o">-</span><span class="mf">17.70859102007032</span>
</code></pre></div>
<p>with an error around
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mrow><mo>−</mo><mn>17</mn></mrow></msup><mo>≈</mo><mroot><mi>ε</mi><mn>3</mn></mroot></mrow><annotation encoding="application/x-tex">2^{-17} \approx \sqrt[3]{\varepsilon}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">17</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.23972em;"></span><span class="mord sqrt"><span class="root"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6585560000000001em;"><span style="top:-2.836336em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8002800000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal">ε</span></span></span><span style="top:-2.76028em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.23972em;"><span></span></span></span></span></span></span></span></span>
as predicted.</p>How Many Ways to Make a (Football) Score2016-01-10T00:00:00-08:002016-01-10T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2016-01-10:/2016/01/how-many-ways-to-make-a-football-score.html<p>While watching today's <a href="https://twitter.com/NFL_Memes/status/686293582672715778">Seahawks-Vikings game</a>, my wife asked:</p>
<blockquote>
<p>How did the Seahawks score 9 points? Did they get a field goal
and miss an extra point after a touchdown?</p>
</blockquote>
<p>I had been head down coding and didn't know the answer. I quickly
jotted down the possibilities (like solving the
<a href="https://en.wikipedia.org/wiki/Change-making_problem">coin-change …</a></p><p>While watching today's <a href="https://twitter.com/NFL_Memes/status/686293582672715778">Seahawks-Vikings game</a>, my wife asked:</p>
<blockquote>
<p>How did the Seahawks score 9 points? Did they get a field goal
and miss an extra point after a touchdown?</p>
</blockquote>
<p>I had been head down coding and didn't know the answer. I quickly
jotted down the possibilities (like solving the
<a href="https://en.wikipedia.org/wiki/Change-making_problem">coin-change problem</a> with coins of value 2, 3, 6, 7 and 8)
and told her it could be one of four outcomes:</p>
<ul>
<li>Field Goal (3), TD with missed PAT (6)</li>
<li>3 Field Goals (3 x 3)</li>
<li>Safety (2), TD (7)</li>
<li>3 Safeties (3 x 2), Field Goal (3)</li>
</ul>
<p>I decided it'd be fun to <a href="https://gist.github.com/dhermes/c5088f4534108743015f">make a tool</a> to answer this question
for any score (not just <strong>9</strong>). Enjoy</p>
<h3>Give me a score, I'll count the ways</h3>
<div>Score: <input type="text" id="num-points" name="numPoints" value="9" style="width: 35px; font-size: 18px;" onchange="bossylobsterBlog.FBScore.updatePage();"></div>
<ol id="scores-list">
<li>1 x Field Goal, 1 x TD with missed PAT</li>
<li>3 x Field Goal</li>
<li>1 x Safety, 1 x TD</li>
<li>3 x Safety, 1 x Field Goal</li>
</ol>
<script src="/js/scoring_possible.js" type="text/javascript"></script>An Interesting Bug2015-07-09T00:00:00-07:002015-07-09T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2015-07-09:/2015/07/an-interesting-bug.html<p>A fairly <a href="http://stackoverflow.com/q/169713/1068170">common</a> interview <a href="http://www.quora.com/Whats-the-hardest-bug-youve-debugged">question</a> is</p>
<blockquote>
<p>What is the "hardest" bug you've dealt with?</p>
</blockquote>
<p>I've both asked it and answered it in interviews. It's pretty rare
that the answer is useful and actionable, but I'll hold off on
commenting on the state of the art in tech interviews today.
(Usually …</p><p>A fairly <a href="http://stackoverflow.com/q/169713/1068170">common</a> interview <a href="http://www.quora.com/Whats-the-hardest-bug-youve-debugged">question</a> is</p>
<blockquote>
<p>What is the "hardest" bug you've dealt with?</p>
</blockquote>
<p>I've both asked it and answered it in interviews. It's pretty rare
that the answer is useful and actionable, but I'll hold off on
commenting on the state of the art in tech interviews today.
(Usually the interviewer defines what "hardest" means or the
interviewee asks for more specifics.)</p>
<p>Though it's been a few years since I've interviewed for jobs, I
still can recall the discomfort at not having a good answer for
this question. (Probably exacerbated by the fact that I was
asking candidates a question I didn't have a good answer to.)</p>
<p>However, I recently acquired a good answer. Immediately after tracking
down a "bug" in the <code>oauth2client</code> library, I realized that I was
set for (interview) life.</p>
<h3>First Contact</h3>
<p>A user reported a <a href="https://github.com/google/oauth2client/issues/193">bug</a> in a library I maintain. The evidence of the
bug was an obscure HTTP response (<code>{'error': 'invalid_grant'}</code>) rather
than an errant code path.</p>
<p>My initial instinct was that for some reason, the user was sending a
malformed request due to encoding issues. This library notoriously
has had many bugs involving the support for Python 2 and 3
simultaneously and these often lead to incorrect representation of
text (mixing up <code>bytes</code> and unicode).</p>
<h3>Debugging</h3>
<p>After some futile back-and-forth on the bug report, it was clear
that I'd need to be on the failing machine to really determine
what was happening. (This was made clear by the fact that the user
could successfully execute the same code on OS X that failed on
an EC2 instance ... <strong>foreshadowing</strong>.)</p>
<p>I hopped onto a screenshare with the user and we went to work.
The first thing we did was to step into the failing <a href="https://github.com/google/oauth2client/blob/fe246ba9bf9044c4f81826825b72e86489bae72d/oauth2client/client.py#L833">line</a>
of code. We ran the failing script with <code>ipython -i</code>
(interactive mode) and then used the <a href="https://ipython.org/ipython-doc/dev/interactive/magics.html#magic-debug"><code>%debug</code> magic</a> to
step into the code right where the exception occurred.</p>
<p>On checking the <a href="http://jwt.io/">JSON web token (JWT)</a> in the <code>body</code>,
it was clear that the header, payload and signed final
segment were correct on both OS X and his EC2 instance.</p>
<h3>Check the Crypto</h3>
<p>Since the plaintext (base64 encoded JSON) header and payload
segments of the JWT were valid, we next stepped into
the <a href="https://github.com/google/oauth2client/blob/fe246ba9bf9044c4f81826825b72e86489bae72d/oauth2client/crypt.py#L384"><code>make_signed_jwt</code> function</a> to ensure that the
JWT signature was being created correctly on both machines.</p>
<p>We even copied and pasted identical header and payload strings
and found <strong>identical</strong> signatures on OS X and the EC2
instance (running Ubuntu).</p>
<h3>Not Crypto, Not Cryptic</h3>
<p>At this point, I was completely perplexed. The request was
seemingly perfectly constructed and — given the same
inputs — both operating systems performed identically.</p>
<p>But the <a href="https://twitter.com/michalmigurski">user</a> that filed the bug had the key insight. The
assumption <strong>"given the same inputs"</strong> was now the point of
failure.</p>
<p>He looked at the payload</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="nt">"aud"</span><span class="p">:</span> <span class="s2">"https://accounts.google.com/o/oauth2/token"</span><span class="p">,</span>
<span class="nt">"exp"</span><span class="p">:</span> <span class="mi">1433902178</span><span class="p">,</span>
<span class="nt">"iat"</span><span class="p">:</span> <span class="mi">1433898578</span><span class="p">,</span>
<span class="nt">"iss"</span><span class="p">:</span> <span class="s2">"1234567890-random-id@developer.gserviceaccount.com"</span><span class="p">,</span>
<span class="nt">"scope"</span><span class="p">:</span> <span class="s2">"https://www.googleapis.com/auth/userinfo.email"</span>
<span class="p">}</span>
</code></pre></div>
<p>and realized the timestamps (<code>exp</code> for expired and <code>iat</code> for
issued at, which are an hour, i.e. 3600 seconds apart) were
drastically different from OS X to the EC2 instance!</p>
<p>These are determined as seconds since the <a href="https://en.wikipedia.org/wiki/Unix_time">epoch</a>:</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="kn">import</span> <span class="nn">datetime</span>
<span class="o">>>></span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">mktime</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">utcnow</span><span class="p">()</span><span class="o">.</span><span class="n">timetuple</span><span class="p">()))</span>
<span class="mi">1433898578</span>
</code></pre></div>
<h3>Final Solution</h3>
<p>After this realization, the answer was quite simple:</p>
<blockquote>
<p>The clock had drifted on the EC2 instance and the time was
wrong. In fact, it was 450 minutes in the past.</p>
</blockquote>
<p>So when the <code>oauth2client</code> library issued requests, it asked
for tokens that expired 390 minutes in the past (an hour past
the "current" time on the machine). Complying with this is
an impossibility, hence the invalid grant error.</p>
<p>This most interesting bug wasn't a bug in the library, but an
incorrectly configured local environment. Once we realized
this fact, the fix was as simple as:</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>sudo ntpdate -s ntp.ubuntu.com
</code></pre></div>Constantly Seek Criticism2014-12-31T00:00:00-08:002014-12-31T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2014-12-31:/2014/12/constantly-seek-criticism.html<p>I was recently catching up on articles and videos I'd been putting off
and came across a great quote from <a href="https://flic.kr/p/d83K9o">Elon Musk</a>:</p>
<blockquote>
<p>A well thought out critique ... is as valuable as gold.
And you should seek that from everyone you can, but particularly your
friends ... It doesn't mean your friends …</p></blockquote><p>I was recently catching up on articles and videos I'd been putting off
and came across a great quote from <a href="https://flic.kr/p/d83K9o">Elon Musk</a>:</p>
<blockquote>
<p>A well thought out critique ... is as valuable as gold.
And you should seek that from everyone you can, but particularly your
friends ... It doesn't mean your friends are right ... you at least want to
listen very carefully to what they say, and to everyone ... Basically,
you should take the approach that you're wrong ... Your goal is to be less
wrong.</p>
</blockquote>
<!-- Full quote: https://gist.github.com/dhermes/b1c3821d7e23722c34b9 -->
<iframe width="560" height="315" src="//www.youtube.com/embed/NU7W7qe2R0A?rel=0&controls=0&showinfo=0&start=640&end=709" frameborder="0" allowfullscreen></iframe>
<p>Many close to me can attest that I greatly admire Elon both as an entrepreneur
and as a scientist. He has proven as a founder of PayPal, SpaceX, and Tesla
that his talent, technical breadth, and sheer persistence are unparalleled.</p>
<p>But this man — more prepared than most on this earth to
tackle such grand challenges — still <strong>seeks out criticism</strong>.</p>
<h2>The Feedback Mindset</h2>
<p>Elon's quote "Constantly Seek Criticism" resonates with me in a real way.
I've been trying to live this for several years. It's a mindset I feel
I had always known, but could never put my fingers on.</p>
<p>The concept became fully clear while visiting family a few years ago.
A cousin described to me how he and his coworkers would pitch business ideas
to each other. The main point of the exercise was to tear every single idea
apart. They entered already aware that most ideas are not good enough. However,
by identifying the weak points, they gained deeper insight into "good ideas"
and learned from each other's prior experience.</p>
<p>It is crucial to have people in our lives to remind us when our ideas are
broken, to call us out when we overstep, or to pull us down to earth when
our aspirations are not rooted here.</p>
<blockquote>
<p>The continued supply of criticism and feedback is a fundamental
part of sustained growth and a key ingredient to success. It is
simple, but simple things can be hard to articulate.</p>
</blockquote>Brand New Blog2014-12-04T00:00:00-08:002014-12-04T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2014-12-04:/2014/12/brand-new-blog.html<p>After a happy 3-year run with <a href="http://bossylobster.blogspot.com/">Blogger</a>, I've decided to
revamp my blog with viewers in mind.</p>
<h2>Why?</h2>
<p>When I <a href="https://blog.bossylobster.com/2011/04/first.html">started</a> my blog, I was still learning the ropes as a
programmer. I was happy to have a place to share the things I learned,
but didn't have much context …</p><p>After a happy 3-year run with <a href="http://bossylobster.blogspot.com/">Blogger</a>, I've decided to
revamp my blog with viewers in mind.</p>
<h2>Why?</h2>
<p>When I <a href="https://blog.bossylobster.com/2011/04/first.html">started</a> my blog, I was still learning the ropes as a
programmer. I was happy to have a place to share the things I learned,
but didn't have much context for the things I was writing.
However, as I started to develop a voice, I became acutely aware
that the look and feel of my blog was bad.</p>
<p>After a good <a href="https://twitter.com/zacharykimball">friend</a> of mine asked me something along the lines
of "Danny, are you blind?", it was clear I needed to make a change.
He solidified what I had known for some time:</p>
<blockquote>
<p>In order to have a voice, I needed more than just content.</p>
</blockquote>
<p>I needed to respect my viewers' tastes by providing a quality visual
experience. This was not clear to me as a freshly minted math nerd from
the University of Michigan.</p>
<p>However, after spending two and a half years at Google building plenty of
slide decks, I knew better. By not writing with viewers in mind, I was
weakening my work by increasing the effort required to consume it.</p>
<p>I hope you're enjoying a more visually pleasing blog
experience and welcome any <a href="https://github.com/dhermes/bossylobster-blog/issues/new">feedback</a> you may have.</p>
<p>Feel free to continue on if you are a nerd like me.</p>
<h2>How?</h2>
<p>I am now hand-crafting HTML for my posts and using a static site
generator for my content. It feels so 90's, but I wasn't using the
internet then, so what do I know?</p>
<p>Inspired by my old buddy <a href="http://brianmannmath.github.io/">Brian</a> and by the insanely productive
<a href="https://jakevdp.github.io/blog/2013/05/07/migrating-from-octopress-to-pelican/">Jake Vanderplas</a>, I decided to port my old content by hand.</p>
<p>The current blog you see here is due to a few main ingredients:</p>
<ul>
<li>The <a href="http://docs.getpelican.com/en/latest/">Pelican</a> static site generator, for the Python hacker in me.</li>
<li>The <a href="https://github.com/duilio/pelican-octopress-theme"><code>octopress</code></a> theme for Pelican. This is arguably the most
important part. Big thanks to the <a href="http://octopress.org/">original</a> theme, I love it!</li>
<li>Static content hosting via <a href="https://pages.github.com/">GitHub Pages</a>. Luckily it's a breeze
to <a href="https://github.com/dhermes/dhermes.github.io/blob/master/CNAME">set up</a> a <a href="https://help.github.com/articles/setting-up-a-custom-domain-with-github-pages/">custom domain</a>.</li>
<li>HTTPS always on and other perks from <a href="https://www.cloudflare.com/">CloudFlare</a>. They claim they
only need five minutes and it is not an exaggeration!</li>
</ul>
<p>Beyond that, I <strong>enhanced</strong> the Pelican dev experience by <a href="https://github.com/dhermes/bossylobster-blog/commit/f578f3c70ea71f4e513c7ff10f5f5afc963b5df4">adding</a>
a way to broadcast within my local network for local testing on
mobile devices. In addition, via <a href="https://travis-ci.org/">Travis</a>, my blog has a <a href="https://github.com/dhermes/bossylobster-blog/blob/master/.travis.yml">build</a>
stage just like real software. This allows the new static content
to be <a href="https://travis-ci.org/dhermes/bossylobster-blog/">built</a> every time I make a new commit to GitHub.</p>
<p>There were plenty of other fun hacks in the 150+ commits it took me
to make the switch, but I'll save that for another post.</p>Quantitative Interview Brain Teaser: Computer Assistance2014-09-28T00:00:00-07:002014-09-28T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2014-09-28:/2014/09/quantitative-interview-brain-teaser.html<p>In a <a href="/2014/09/quantitative-brain-teaser-brain-only.html">previous post</a>
I discussed a recent brain teaser I had come across:</p>
<blockquote>
<p>Find a <strong>10-digit number</strong>, where each digit represents the
number of that ordinal number in the whole number. So, the
<strong>first digit represents the number of 0's</strong> in the whole 10 digits. The
second digit represents …</p></blockquote><p>In a <a href="/2014/09/quantitative-brain-teaser-brain-only.html">previous post</a>
I discussed a recent brain teaser I had come across:</p>
<blockquote>
<p>Find a <strong>10-digit number</strong>, where each digit represents the
number of that ordinal number in the whole number. So, the
<strong>first digit represents the number of 0's</strong> in the whole 10 digits. The
second digit represents the number of 1's in the whole 10 digits. And
so on. The first digit is not a 0.</p>
</blockquote>
<p>As I promised at the end of the "brain only" post, we'll do better than
simply finding <strong>an</strong> answer, we'll find all of them (with the aid of a
computer).</p>
<h4>Making the Problem Smaller</h4>
<p>Without any thinking, there are 9 billion
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>9</mn><mo>⋅</mo><mn>1</mn><msup><mn>0</mn><mn>9</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(9 \cdot 10^9)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">9</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">9</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>
total choices. This is not only intractable for the human brain, but
becomes difficult for a computer too. A 3 GHz processor in the most
optimal case can only perform 3 billion operations per second but there
is a lot of counting, lists to create, and otherwise to find a number
which fits the criteria. To start, we write our number as</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>n</mi><mo>=</mo><msub><mi>d</mi><mn>0</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>1</mn></msub><msub><mi>d</mi><mn>2</mn></msub><msub><mi>d</mi><mn>3</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>4</mn></msub><msub><mi>d</mi><mn>5</mn></msub><msub><mi>d</mi><mn>6</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>7</mn></msub><msub><mi>d</mi><mn>8</mn></msub><msub><mi>d</mi><mn>9</mn></msub></mrow><annotation encoding="application/x-tex">n = d_0, d_1 d_2 d_3, d_4 d_5 d_6, d_7 d_8 d_9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">7</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">9</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Since there are 10 digits in total and each of the digits represent a
subcount of occurrences, the total number of occurrences can be
represented as the sum:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>+</mo><msub><mi>d</mi><mn>1</mn></msub><mo>+</mo><msub><mi>d</mi><mn>2</mn></msub><mo>+</mo><msub><mi>d</mi><mn>3</mn></msub><mo>+</mo><msub><mi>d</mi><mn>4</mn></msub><mo>+</mo><msub><mi>d</mi><mn>5</mn></msub><mo>+</mo><msub><mi>d</mi><mn>6</mn></msub><mo>+</mo><msub><mi>d</mi><mn>7</mn></msub><mo>+</mo><msub><mi>d</mi><mn>8</mn></msub><mo>+</mo><msub><mi>d</mi><mn>9</mn></msub><mo>=</mo><mn>10</mn></mrow><annotation encoding="application/x-tex">d_0 + d_1 + d_2 + d_3 + d_4 + d_5 + d_6 + d_7 + d_8 + d_9 = 10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">7</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">9</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">10</span></span></span></span></span>
</blockquote></div>
<p>Additionally, (for example) since each 3 contributes a value of 3 to the
digit sum, we must also have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>d</mi><mn>1</mn></msub><mo>+</mo><mn>2</mn><msub><mi>d</mi><mn>2</mn></msub><mo>+</mo><mn>3</mn><msub><mi>d</mi><mn>3</mn></msub><mo>+</mo><mn>4</mn><msub><mi>d</mi><mn>4</mn></msub><mo>+</mo><mn>5</mn><msub><mi>d</mi><mn>5</mn></msub><mo>+</mo><mn>6</mn><msub><mi>d</mi><mn>6</mn></msub><mo>+</mo><mn>7</mn><msub><mi>d</mi><mn>7</mn></msub><mo>+</mo><mn>8</mn><msub><mi>d</mi><mn>8</mn></msub><mo>+</mo><mn>9</mn><msub><mi>d</mi><mn>9</mn></msub><mo>=</mo><mn>10</mn></mrow><annotation encoding="application/x-tex">d_1 + 2 d_2 + 3 d_3 + 4 d_4 + 5 d_5 + 6 d_6 + 7 d_7 + 8 d_8 + 9 d_9 = 10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">3</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">6</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">7</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">7</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">8</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">9</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">9</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">10</span></span></span></span></span>
</blockquote></div>
<p>This second equation (which requires the first to make sense) limits our
choices of digits a great deal:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>0</mn><mo>≤</mo><msub><mi>d</mi><mn>5</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>6</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>7</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>8</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>9</mn></msub><mo>≤</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">0 \leq d_5, d_6, d_7, d_8, d_9 \leq 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.78041em;vertical-align:-0.13597em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">7</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">9</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span></span>
</blockquote></div>
<p>The last four are obvious since (for example)
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mo>⋅</mo><mn>6</mn><mo>></mo><mn>10</mn></mrow><annotation encoding="application/x-tex">2 \cdot 6 > 10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68354em;vertical-align:-0.0391em;"></span><span class="mord">6</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">10</span></span></span></span>.
We can also say that
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>5</mn></msub><mo><</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">d_5 < 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>.
It is clearly no bigger than 2 but in the case that
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>5</mn></msub><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">d_5 = 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>
we'd also have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>2</mn></msub><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">d_2 > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>
meaning
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><msub><mi>d</mi><mn>2</mn></msub><mo>+</mo><mn>5</mn><msub><mi>d</mi><mn>5</mn></msub><mo>=</mo><mn>2</mn><msub><mi>d</mi><mn>2</mn></msub><mo>+</mo><mn>10</mn><mo>></mo><mn>10</mn></mrow><annotation encoding="application/x-tex">2 d_2 + 5 d_5 = 2 d_2 + 10 > 10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68354em;vertical-align:-0.0391em;"></span><span class="mord">10</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">10</span></span></span></span>.
Thus to brute force the problem we can choose digits 5 through
9 (5 digits in total) from the 32 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msup><mn>2</mn><mn>5</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(2^5)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>
different possible ways to make them 0 or 1.</p>
<h4>Listing All Choices</h4>
<p>Now for the fun part: programming (in Python). We now have 90,000
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>9</mn><mo>⋅</mo><mn>1</mn><msup><mn>0</mn><mn>4</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(9 \cdot 10^4)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">9</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> choices for our first 5 digits
and 32 choices for our last 5 digits.</p>
<p>We can use Python's <code>range(10**4, 10**5)</code> to represent the 5-digit
numbers between 10,000 and 99,999 (inclusive). For the 32 choices
for the last 5 digits, we use <code>itertools.product</code>.</p>
<p>To see it in action on a smaller set of data:</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="kn">import</span> <span class="nn">itertools</span>
<span class="o">>>></span> <span class="k">for</span> <span class="n">pair</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">product</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">repeat</span><span class="o">=</span><span class="mi">2</span><span class="p">):</span>
<span class="o">...</span> <span class="nb">print</span> <span class="n">pair</span>
<span class="o">...</span>
<span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<p>When we ask for 5 repeated
copies of the tuple <code>(0, 1)</code> we get 32 possible 5-tuples as expected:</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="nb">len</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">itertools</span><span class="o">.</span><span class="n">product</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">repeat</span><span class="o">=</span><span class="mi">5</span><span class="p">)))</span>
<span class="mi">32</span>
</code></pre></div>
<h4>Checking Candidates</h4>
<p>Before we can iterate through all of our combinations, we need a way to
check if a given number fits the criterion. To do that we implement</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">fits_criterion</span><span class="p">(</span><span class="n">digit_list</span><span class="p">):</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="k">if</span> <span class="n">digit_list</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">!=</span> <span class="n">digit_list</span><span class="p">[</span><span class="n">i</span><span class="p">]:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="kc">True</span>
</code></pre></div>
<p>This
takes a <code>list</code> of digits, so as we loop over all choices, we'll turn
them into lists.</p>
<h4>Exhaustive Search</h4>
<p>Now we can use our accumulated tools, loop through all choices and print
any matches</p>
<div class="highlight"><pre><span></span><code><span class="k">for</span> <span class="n">first5</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="mi">10</span><span class="o">**</span><span class="mi">4</span><span class="p">,</span> <span class="mi">10</span><span class="o">**</span><span class="mi">5</span><span class="p">):</span>
<span class="n">first5_list</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">first5</span><span class="p">))</span>
<span class="k">for</span> <span class="n">last5</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">product</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">repeat</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
<span class="n">digit_list</span> <span class="o">=</span> <span class="n">first5_list</span> <span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="n">last5</span><span class="p">)</span> <span class="c1"># last5 is a tuple</span>
<span class="k">if</span> <span class="n">fits_criterion</span><span class="p">(</span><span class="n">digit_list</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">digit_list</span>
</code></pre></div>
<p>As luck would have it, the output is simply</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span>
</code></pre></div>
<p>In other words,
the only number which fits the criteria is the one we found with our
brains alone:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>6</mn><mo separator="true">,</mo><mn>210</mn><mo separator="true">,</mo><mn>001</mn><mo separator="true">,</mo><mn>000</mn></mrow><annotation encoding="application/x-tex">6,210,001,000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">6</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">210</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">001</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span></span></span></span></span>
</blockquote></div>
<p>This serves to make the interview question that much more difficult,
since there is a unique solution.</p>Quantitative Brain Teaser: Brain Only2014-09-22T00:00:00-07:002014-09-22T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2014-09-22:/2014/09/quantitative-brain-teaser-brain-only.html<p>I've recently been working some atrophied mental muscles and came across
a brain teaser that was pretty nifty:</p>
<blockquote>
<p>Find a <strong>10-digit number</strong>, where each digit represents the
number of that ordinal number in the whole number. So, the
<strong>first digit represents the number of 0's</strong> in the whole 10 digits …</p></blockquote><p>I've recently been working some atrophied mental muscles and came across
a brain teaser that was pretty nifty:</p>
<blockquote>
<p>Find a <strong>10-digit number</strong>, where each digit represents the
number of that ordinal number in the whole number. So, the
<strong>first digit represents the number of 0's</strong> in the whole 10 digits. The
second digit represents the number of 1's in the whole 10 digits. And
so on. The first digit is not a 0.</p>
</blockquote>
<h4>Example</h4>
<p>If we shortened from 10 digits to 4 digit, the number</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>2</mn><mo separator="true">,</mo><mn>020</mn></mrow><annotation encoding="application/x-tex">2,020</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">020</span></span></span></span></span>
</blockquote></div>
<p>works since we have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">d_0 = 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>
and two 0's (in the second and fourth slots),
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>1</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">d_1 = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>
since the number has no 1's,
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>2</mn></msub><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">d_2 = 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>
since the number has two 2's (in the first and third slots) and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>3</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">d_3 = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>
since the number has no 3's.</p>
<h4>Shorthand Notation</h4>
<p>In order to refer to each digit, for search we name them all:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>n</mi><mo>=</mo><msub><mi>d</mi><mn>0</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>1</mn></msub><msub><mi>d</mi><mn>2</mn></msub><msub><mi>d</mi><mn>3</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>4</mn></msub><msub><mi>d</mi><mn>5</mn></msub><msub><mi>d</mi><mn>6</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>7</mn></msub><msub><mi>d</mi><mn>8</mn></msub><msub><mi>d</mi><mn>9</mn></msub></mrow><annotation encoding="application/x-tex">n = d_0, d_1 d_2 d_3, d_4 d_5 d_6, d_7 d_8 d_9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">7</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">9</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>We can see this in the above example when we refer to the digits in the
four digit number</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>n</mi><mo>=</mo><msub><mi>d</mi><mn>0</mn></msub><mo separator="true">,</mo><msub><mi>d</mi><mn>1</mn></msub><msub><mi>d</mi><mn>2</mn></msub><msub><mi>d</mi><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">n = d_0, d_1 d_2 d_3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<h4>A Practical Approach, Breaking Into Subproblems</h4>
<p>Our search space is massive, and with only our wits, we need to quickly
find a way to focus on a small space of possibilities. Since the first
digit allows us to place a number of 0's we try to set it equal to
values starting from the largest. By doing this we only have a little
wiggle room to find the places which don't hold a zero.</p>
<h4>First Case: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>=</mo><mn>9</mn></mrow><annotation encoding="application/x-tex">d_0 = 9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">9</span></span></span></span></h4>
<p>In this case our only choice is</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>9</mn><mo separator="true">,</mo><mn>000</mn><mo separator="true">,</mo><mn>000</mn><mo separator="true">,</mo><mn>000</mn></mrow><annotation encoding="application/x-tex">9,000,000,000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">9</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span></span></span></span></span>
</blockquote></div>
<p>since we must have nine 0's. However since we have one 9,
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>9</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">d_9 = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">9</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>
should not occur.</p>
<p>Thus we see <strong>none of our choices are possible</strong> when
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>=</mo><mn>9</mn></mrow><annotation encoding="application/x-tex">d_0 = 9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">9</span></span></span></span>.</p>
<h4>Second Case: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>=</mo><mn>8</mn></mrow><annotation encoding="application/x-tex">d_0 = 8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">8</span></span></span></span></h4>
<p>Here we must have eight 0's and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>8</mn></msub><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">d_8 > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>
so our possible solutions must look like</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>8</mn><mo separator="true">,</mo><mn>000</mn><mo separator="true">,</mo><mn>000</mn><mo separator="true">,</mo><mn>0</mn><mo>∗</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">8,000,000,0*0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">8</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span></span>
</blockquote></div>
<p>But this leaves us with
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>8</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">d_8 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">8</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>
as our only choice since we can't place any more 8's. But now the
presence of a 1 in</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>8</mn><mo separator="true">,</mo><mn>000</mn><mo separator="true">,</mo><mn>000</mn><mo separator="true">,</mo><mn>010</mn></mrow><annotation encoding="application/x-tex">8,000,000,010</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">8</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">010</span></span></span></span></span>
</blockquote></div>
<p>can't coexist with
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>1</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">d_1 = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>
so we again see <strong>none of our choices are possible</strong> when
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>=</mo><mn>8</mn></mrow><annotation encoding="application/x-tex">d_0 = 8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">8</span></span></span></span>.</p>
<h4>Third Case: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>=</mo><mn>7</mn></mrow><annotation encoding="application/x-tex">d_0 = 7</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">7</span></span></span></span></h4>
<p>Here we have seven 0's and know that
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>7</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">d_7 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">7</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>
It must be at least 1 since the first digit is a 7. It can't be 2
because the presence of another 7 would mean another digit (other than
0) would occur 7 times, which is impossible since there are only 10
total digits.</p>
<p>Since we know
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>7</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">d_7 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">7</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>
our possible solutions must look like</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>7</mn><mo separator="true">,</mo><mo>∗</mo><mn>00</mn><mo separator="true">,</mo><mn>000</mn><mo separator="true">,</mo><mn>100</mn></mrow><annotation encoding="application/x-tex">7,*00,000,100</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">7</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∗</span><span class="mord">00</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">100</span></span></span></span></span>
</blockquote></div>
<p>But again here we reach an impossible point. If we set
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>1</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">d_1 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>
then that digit would contradict itself since it is the second
occurrence of 1. If
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>1</mn></msub><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">d_1 = 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>
it would contradict
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>2</mn></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">d_2 = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>
and so on for higher values. In addition, we have used all our
digits, so can't increase the value of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">d_1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>
by placing more 1's in our number.</p>
<p>Thus we see <strong>none of our choices are possible</strong> when
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>=</mo><mn>7</mn></mrow><annotation encoding="application/x-tex">d_0 = 7</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">7</span></span></span></span>.</p>
<h4>Fourth Case: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>0</mn></msub><mo>=</mo><mn>6</mn></mrow><annotation encoding="application/x-tex">d_0 = 6</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">6</span></span></span></span></h4>
<p>Here we have six 0's and must have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>6</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">d_6 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>
since (as above), two different digits can't occur six times among 10
digits.</p>
<p>Also as before we can't have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>1</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">d_1 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>
but now have some extra freedom (an extra digit which doesn't have to
be 0) so consider the case
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>1</mn></msub><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">d_1 = 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>.
This corresponds to an occurrence of the digit 2, hence we set
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>d</mi><mn>2</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">d_2 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>.</p>
<p>Now we have 4 nonzero digits along with six 0's to place:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>6</mn><mo separator="true">,</mo><mn>210</mn><mo separator="true">,</mo><mn>001</mn><mo separator="true">,</mo><mn>000</mn></mrow><annotation encoding="application/x-tex">6,210,001,000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">6</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">210</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">001</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">000</span></span></span></span></span>
</blockquote></div>
<p>Thus <strong>we have found a number</strong> which satisfies the criteria!
The zero digits in the 3, 4, 5, 7, 8, and 9 places correspond to the
absence of those digits. The nonzero digits in the 0, 1, 2, and 6
places also are the correct counts of each of those digits.</p>
<p>As a math nerd, I was still curious to know how to find every possible
number that satisfies the criteria, but that task is too tedious to
handle with the brain alone (or at least to be worth reading about when
solved by hand). In my follow up to this, I'll show how a combination of
smarts and programming can perform an exhaustive search in under 10
seconds.</p>Math for Humans, A Second Attempt2014-08-22T00:00:00-07:002014-08-22T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2014-08-22:/2014/08/math-for-humans-second-attempt.html<p>The morning after posting my latest
<a href="/2014/07/conditional-probabilities-in-thinking.html">blog post</a>,
I woke up still thinking about how to explain the concept.</p>
<p>More importantly, I realized that my goal of writing
<strong>math for humans</strong> failed miserably.</p>
<p>So here is a second go at it.</p>
<p>First we're told we're in a world where <strong>85 …</strong></p><p>The morning after posting my latest
<a href="/2014/07/conditional-probabilities-in-thinking.html">blog post</a>,
I woke up still thinking about how to explain the concept.</p>
<p>More importantly, I realized that my goal of writing
<strong>math for humans</strong> failed miserably.</p>
<p>So here is a second go at it.</p>
<p>First we're told we're in a world where <strong>85% of cabs are Green</strong>
and the rest are Blue. Humans love tables (and they are
easy to understand). So we start off with a representative sample of 100
cabs:</p>
<!--- http://blogknowhow.blogspot.com/2011/01/how-add-table-blogger-blogspot-post.html -->
<style type="text/css">
.nobrtable br { display: none }
.nobrtable tr {text-align: center;}
.nobrtable tr.alt td {background-color: #eeeecc; color: black;}
.nobrtable td {text-align: center;}
.nobrtable caption {caption-side:bottom;}
</style>
<div style="margin-left: auto; margin-right: auto; text-align: center;">
<div class="nobrtable">
<table border="2" bordercolor="#0033FF" cellpadding="10" cellspacing="0" style="background-color: #99ffff; border-collapse: collapse; color: black; margin-left: auto; margin-right: auto; width: 100%px;">
<tbody>
<tr style="background-color: #0033ff; color: white; padding-bottom: 4px; padding-top: 5px;">
<th>Category</th>
<th>Green</th>
<th>Blue</th>
<th>Total</th>
</tr>
<tr class="alt">
<td>Cabs</td>
<td>85</td>
<td>15</td>
<td>100</td>
</tr>
</tbody></table>
</div>
</div>
<p>After this, we're told that a bystander
<strong>correctly identifies a cab 80% of the time</strong>, or 4 out of every 5.
Applying this to the 85 Green cabs (85 is 17 times 5), this bystander
will mis-identify 17 as Blue (1 out of 5) and the other 68 will
correctly be identified as Green:</p>
<div style="margin-left: auto; margin-right: auto; text-align: center;">
<div class="nobrtable">
<table border="2" bordercolor="#0033FF" cellpadding="10" cellspacing="0" style="background-color: #99ffff; border-collapse: collapse; color: black; margin-left: auto; margin-right: auto; width: 100%px;">
<tbody>
<tr style="background-color: #0033ff; color: white; padding-bottom: 4px; padding-top: 5px;">
<th>Category</th>
<th>Green</th>
<th>Blue</th>
<th>Total</th>
</tr>
<tr class="alt">
<td>Cabs</td>
<td>85</td>
<td>15</td>
<td>100</td>
</tr>
<tr>
<td>ID'd Green</td>
<td><b>68</b></td>
<td></td>
<td></td>
</tr>
<tr class="alt">
<td>ID'd Blue</td>
<td><b>17</b></td>
<td></td>
<td></td>
</tr>
</tbody></table>
</div>
</div>
<p>Similarly, of the 15 Blue cabs (15 is 3 times 5), this bystander will
mis-identify 3 as Green (1 out of 5) and the other 12 will correctly be
identified as Blue:</p>
<div style="margin-left: auto; margin-right: auto; text-align: center;">
<div class="nobrtable">
<table border="2" bordercolor="#0033FF" cellpadding="10" cellspacing="0" style="background-color: #99ffff; border-collapse: collapse; color: black; margin-left: auto; margin-right: auto; width: 100%px;">
<tbody>
<tr style="background-color: #0033ff; color: white; padding-bottom: 4px; padding-top: 5px;">
<th>Category</th>
<th>Green</th>
<th>Blue</th>
<th>Total</th>
</tr>
<tr class="alt">
<td>Cabs</td>
<td>85</td>
<td>15</td>
<td>100</td>
</tr>
<tr>
<td>ID'd Green</td>
<td>68</td>
<td><b>3</b></td>
<td></td>
</tr>
<tr class="alt">
<td>ID'd Blue</td>
<td>17</td>
<td><b>12</b></td>
<td></td>
</tr>
</tbody></table>
</div>
</div>
<p>Now Kahneman wants us to use the data at hand to determine what the
probability is that a cab is <span>actually Blue</span> given the
bystander <strong>identified the cab as Blue</strong>. To determine this
probability, we simply need to consider the final row of the table:</p>
<div style="margin-left: auto; margin-right: auto; text-align: center;">
<div class="nobrtable">
<table border="2" bordercolor="#0033FF" cellpadding="10" cellspacing="0" style="background-color: #99ffff; border-collapse: collapse; color: black; margin-left: auto; margin-right: auto; width: 100%px;">
<tbody>
<tr style="background-color: #0033ff; color: white; padding-bottom: 4px; padding-top: 5px;">
<th>Category</th>
<th>Green</th>
<th>Blue</th>
<th>Total</th>
</tr>
<tr class="alt">
<td>ID'd Blue</td>
<td>17</td>
<td>12</td>
<td><b>29</b></td>
</tr>
</tbody></table>
</div>
</div>
<p>This rows tells us that only 29 cabs will be identified as Blue, and
among those, 12 will actually be Blue. Hence the probability will be</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><mn>12</mn><mn>29</mn></mfrac><mo>≈</mo><mn>0.413793103</mn></mrow><annotation encoding="application/x-tex">\frac{12}{29} \approx 0.413793103</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">29</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">12</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.413793103</span></span></span></span></span>
</blockquote></div>
<p>What this really shows is that even though the bystander has a large
chance (80%) of getting the color right, the number of Green cabs is
so much larger it overwhelms the correctly identified Blue cabs with
incorrectly identified Green ones.</p>
<h2>What I Overlooked</h2>
<ul>
<li>Dense text is always bad</li>
<li>Using colors and breaking up text makes reading easier (more
modular)</li>
<li>Introducing mathematical notation is almost always overkill</li>
<li>Tables and samples are a good way to discuss probabilities</li>
</ul>Bayes' Law Primer2014-07-29T00:00:00-07:002014-07-29T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2014-07-29:/2014/07/bayes-law-primer.html<p>I'm currently writing a blog post that uses
<a href="http://en.wikipedia.org/wiki/Bayes%27_law">Bayes' Law</a>
but don't want to muddy the post with a review in layman's terms. So
I have something to link, here is a short description and a chance to flex my
<a href="http://math.berkeley.edu/~dhermes/">teaching</a> muscles before the school
year starts.</p>
<h2>Bayes' Law</h2>
<p>For …</p><p>I'm currently writing a blog post that uses
<a href="http://en.wikipedia.org/wiki/Bayes%27_law">Bayes' Law</a>
but don't want to muddy the post with a review in layman's terms. So
I have something to link, here is a short description and a chance to flex my
<a href="http://math.berkeley.edu/~dhermes/">teaching</a> muscles before the school
year starts.</p>
<h2>Bayes' Law</h2>
<p>For those who aren't sure, Bayes' Law tells us that the probability
event
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span></span></span></span>
occurs given we know that event
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi></mrow><annotation encoding="application/x-tex">Y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span></span>
has occurred can
easily be computed. It is written as
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>Y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\text{Pr}(X \, | \, Y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span></span></span></span>
vertical bar is meant like the word "given", in other words, the event
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span></span></span></span>
is distinct from the event
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>X</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>Y</mi><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">(X \, | \, Y),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> i.e.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span></span></span></span> given <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi></mrow><annotation encoding="application/x-tex">Y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span></span>.
Bayes' law, states that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>Y</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> and </mtext><mi>Y</mi><mtext> both occur</mtext><mo stretchy="false">)</mo></mrow><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>Y</mi><mo stretchy="false">)</mo></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\text{Pr}(X \, | \, Y) = \frac{\text{Pr}(X \text{ and } Y \text{ both occur})}{\text{Pr}(Y)}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord text"><span class="mord"> and </span></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>This effectively is a re-scaling of the events by the total probability
of the given event:
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>Y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\text{Pr}(Y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span></span></span></span>.</p>
<p>For example, if <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span></span></span></span> is the event that a <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn></mrow><annotation encoding="application/x-tex">3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span>
is rolled on a fair die and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi></mrow><annotation encoding="application/x-tex">Y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span></span> is the event that the roll
is odd. We know of course that
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>Y</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">\text{Pr}(Y) = \frac{1}{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>
since half of the rolls are odd. The event
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mtext> and </mtext><mi>Y</mi><mtext> both occur</mtext></mrow><annotation encoding="application/x-tex">X \text{ and } Y \text{ both occur}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord text"><span class="mord"> and </span></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mord text"><span class="mord"> both occur</span></span></span></span></span>
in this case is the same as <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi></mrow><annotation encoding="application/x-tex">X</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span></span></span></span> since the roll can only be
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn></mrow><annotation encoding="application/x-tex">3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span> if the roll is already odd. Thus</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> and </mtext><mi>Y</mi><mtext> both occur</mtext><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mn>6</mn></mfrac></mrow><annotation encoding="application/x-tex">\text{Pr}(X \text{ and } Y \text{ both occur}) = \frac{1}{6}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord text"><span class="mord"> and </span></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">6</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>and we can compute the conditional probability</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>Y</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>6</mn></mrow><mrow><mn>1</mn><mi mathvariant="normal">/</mi><mn>2</mn></mrow></mfrac><mo>=</mo><mfrac><mn>1</mn><mn>3</mn></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\text{Pr}(X \, | \, Y) = \frac{1 / 6}{1 / 2} = \frac{1}{3}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1/2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1/6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>As we expect, one out of every three odd rolls is a <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn></mrow><annotation encoding="application/x-tex">3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span>.</p>
<h2 id="extended">Bayes' Law Extended Form</h2>
<p>Instead of considering a single event <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">Y,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="mpunct">,</span></span></span></span> we can consider
a range of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> possible events
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>Y</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>Y</mi><mn>2</mn></msub><mo separator="true">,</mo><mo>…</mo><mo separator="true">,</mo><msub><mi>Y</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">Y_1, Y_2, \ldots, Y_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>
occur. We require that one of these <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi></mrow><annotation encoding="application/x-tex">Y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span></span>-events must occur
and that they cover all possible events that could occur. For example
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>Y</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">Y_1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the event that H<sub>2</sub>O is vapor,
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>Y</mi><mn>2</mn></msub></mrow><annotation encoding="application/x-tex">Y_2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the event that H<sub>2</sub>O is water and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>Y</mi><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">Y_3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the event that H<sub>2</sub>O is ice.</p>
<p>In such a case we know that since the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Y</mi></mrow><annotation encoding="application/x-tex">Y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span></span></span></span>-events are distinct</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mo stretchy="false">)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> and </mtext><msub><mi>Y</mi><mn>1</mn></msub><mtext> both occur</mtext><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>+</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> and </mtext><msub><mi>Y</mi><mn>2</mn></msub><mtext> both occur</mtext><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>+</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> and </mtext><msub><mi>Y</mi><mn>3</mn></msub><mtext> both occur</mtext><mo stretchy="false">)</mo><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} \text{Pr}(X) &= \text{Pr}(X \text{ and } Y_1 \text{ both occur}) \\ &+ \text{Pr}(X \text{ and } Y_2 \text{ both occur}) \\ &+ \text{Pr}(X \text{ and } Y_3 \text{ both occur}). \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:4.500000000000002em;vertical-align:-2.000000000000001em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.5000000000000004em;"><span style="top:-4.66em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mclose">)</span></span></span><span style="top:-3.16em;"><span class="pstrut" style="height:3em;"></span><span class="mord"></span></span><span style="top:-1.6599999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.000000000000001em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.5000000000000004em;"><span style="top:-4.66em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord text"><span class="mord"> and </span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span></span></span><span style="top:-3.16em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord text"><span class="mord"> and </span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span></span></span><span style="top:-1.6599999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord text"><span class="mord"> and </span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.000000000000001em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Using Bayes' law, we can reinterpret as</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> and </mtext><msub><mi>Y</mi><mi>j</mi></msub><mtext> both occur</mtext><mo stretchy="false">)</mo><mo>=</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><msub><mi>Y</mi><mi>j</mi></msub><mo stretchy="false">)</mo><mo>⋅</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><msub><mi>Y</mi><mi>j</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\text{Pr}(X \text{ and } Y_j \text{ both occur}) = \text{Pr}(X \, | \, Y_j) \cdot \text{Pr}(Y_j)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord text"><span class="mord"> and </span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span>
</blockquote></div>
<p>and the above becomes</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mo stretchy="false">)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><msub><mi>Y</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo>⋅</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><msub><mi>Y</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo>+</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><msub><mi>Y</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo>⋅</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><msub><mi>Y</mi><mn>2</mn></msub><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>+</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>X</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><msub><mi>Y</mi><mn>3</mn></msub><mo stretchy="false">)</mo><mo>⋅</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><msub><mi>Y</mi><mn>3</mn></msub><mo stretchy="false">)</mo><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} \text{Pr}(X) &= \text{Pr}(X \, | \, Y_1) \cdot \text{Pr}(Y_1) + \text{Pr}(X \, | \, Y_2) \cdot \text{Pr}(Y_2) \\ &+ \text{Pr}(X \, | \, Y_3) \cdot \text{Pr}(Y_3). \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.0000000000000004em;vertical-align:-1.2500000000000002em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mclose">)</span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.22222em;">Y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.22222em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>The same is true if we replace <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn></mrow><annotation encoding="application/x-tex">3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span> with an arbitrary number of
events <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span>.</p>Conditional Probabilities in "Thinking Fast and Slow"2014-07-29T00:00:00-07:002014-07-29T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2014-07-29:/2014/07/conditional-probabilities-in-thinking.html<p>I'm currently reading
<a href="http://www.amazon.com/gp/product/0374533555/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0374533555&linkCode=as2&tag=boslobblo-20&linkId=FMJCYK4RKIVWRNFH">Thinking, Fast and Slow</a><img src="//ir-na.amazon-adsystem.com/e/ir?t=boslobblo-20&l=as2&o=1&a=0374533555" width="1" height="1" border="0" alt="AMZN Affiliate Ad" style="border:none !important; margin:0px !important;" />
by <a href="http://en.wikipedia.org/wiki/Daniel_Kahneman">Daniel Kahneman</a>.
(Thanks to Elianna for letting me borrow it.) I'm not finished yet, but
60% of the way through I definitely recommend it.</p>
<p>While reading the "Causes Trump Statistics" chapter (number 16), there
is a description of a study about cabs …</p><p>I'm currently reading
<a href="http://www.amazon.com/gp/product/0374533555/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0374533555&linkCode=as2&tag=boslobblo-20&linkId=FMJCYK4RKIVWRNFH">Thinking, Fast and Slow</a><img src="//ir-na.amazon-adsystem.com/e/ir?t=boslobblo-20&l=as2&o=1&a=0374533555" width="1" height="1" border="0" alt="AMZN Affiliate Ad" style="border:none !important; margin:0px !important;" />
by <a href="http://en.wikipedia.org/wiki/Daniel_Kahneman">Daniel Kahneman</a>.
(Thanks to Elianna for letting me borrow it.) I'm not finished yet, but
60% of the way through I definitely recommend it.</p>
<p>While reading the "Causes Trump Statistics" chapter (number 16), there
is a description of a study about cabs and hit-and-run accidents. It
describes a scenario where participants are told that 85% of cabs are
Green, 15% are Blue and a given observer has an 80% chance of correctly
identifying the color of a given cab. Given this data, the chapter
presents a scenario where a bystander identifies a cab in an accident as
Blue and Kahneman goes on to explain how we fail to take the data into
consideration. I really enjoyed this chapter, but won't wreck the book
for you.</p>
<p>Instead, I want to do some math (big surprise, I know). However, I want
to make it accessible to non-mathematicians (atypical for my posts).</p>
<p>Given the data, Kahneman tells us that the true probability that the cab
was Blue is 41% though we likely bias our thinking towards the 80%
probability of the identification being correct. I was on the
<a href="http://www.sfmta.com/">bus</a> and it kept bothering me, to the point that
I couldn't continue reading. Eventually I figured it out (when I got to
the <a href="http://www.bart.gov/">train</a>) and I wanted to explain how this is
computed using <a href="http://en.wikipedia.org/wiki/Bayes%27_law">Bayes' Law</a>.
As a primer, I wrote a
<a href="/2014/07/bayes-law-primer.html">post</a> using
layman's terms explaining how we use Bayes' Law. (There is some notation
introduced but I hope it isn't too confusing.)</p>
<h2>Putting Bayes' Law to Use</h2>
<p>We need to understand what 41% even corresponds to before we can compute
it. What's actually happened is that we know the event
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>I</mi><mi>D</mi><mi>B</mi></mrow><annotation encoding="application/x-tex">IDB</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> has occurred — the cab has been identified
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(ID)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mclose">)</span></span></span></span> as Blue <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>B</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(B)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span></span></span></span>.
What we want is the probability that the cab <strong>is Blue</strong> given we know
it has been identified — we want:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>I</mi><mi>D</mi><mi>B</mi><mo stretchy="false">)</mo><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\text{Pr}(B \, | \, IDB).</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Using Bayes' Law, we can write</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>I</mi><mi>D</mi><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mtext> and </mtext><mi>I</mi><mi>D</mi><mi>B</mi><mtext> both occur</mtext><mo stretchy="false">)</mo></mrow><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mo stretchy="false">)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">\text{Pr}(B \, | \, IDB) = \frac{\text{Pr}(B \text{ and } IDB \text{ both occur})}{\text{Pr}(IDB)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord text"><span class="mord"> and </span></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>and</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mtext> and </mtext><mi>I</mi><mi>D</mi><mi>B</mi><mtext> both occur</mtext><mo stretchy="false">)</mo></mrow><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mo stretchy="false">)</mo></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\text{Pr}(IDB \, | \, B) = \frac{\text{Pr}(B \text{ and } IDB \text{ both occur})}{\text{Pr}(B)}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord text"><span class="mord"> and </span></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>identified 80% of the time hence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mn>0.8</mn></mrow><annotation encoding="application/x-tex">\text{Pr}(IDB \, | \, B) = 0.8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.8</span></span></span></span></span>
</blockquote></div>
<p>(i.e. the probability of correct ID
as Blue given it is actually Blue). We're also told that 15% of the cabs
are Blue hence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mn>0.15.</mn></mrow><annotation encoding="application/x-tex">\text{Pr}(B) = 0.15.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.15.</span></span></span></span></span>
</blockquote></div>
<p>We can combine these with the second
application of Bayes' Law above to show that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mtext> and </mtext><mi>I</mi><mi>D</mi><mi>B</mi><mtext> both occur</mtext><mo stretchy="false">)</mo><mo>=</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>B</mi><mo stretchy="false">)</mo><mo>⋅</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mn>0.12.</mn></mrow><annotation encoding="application/x-tex">\text{Pr}(B \text{ and } IDB \text{ both occur}) = \text{Pr}(IDB \, | \, B) \cdot \text{Pr}(B) = 0.12.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord text"><span class="mord"> and </span></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.12.</span></span></span></span></span>
</blockquote></div>
<p>The only piece of data missing now to finish our computation is
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\text{Pr}(IDB)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span></span></span></span>.</p>
<p>Using the
<a href="ster.com/2014/07/bayes-law-primer.html#extended">extended form</a>
of Bayes' Law, since we know that the events <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi></mrow><annotation encoding="application/x-tex">B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>G</mi></mrow><annotation encoding="application/x-tex">G</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">G</span></span></span></span> (the cab is Blue or Green) are exclusive and cover all
possibilities for the cab, we can say that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>B</mi><mo stretchy="false">)</mo><mo>⋅</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mo stretchy="false">)</mo><mo>+</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>G</mi><mo stretchy="false">)</mo><mo>⋅</mo><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>G</mi><mo stretchy="false">)</mo><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\text{Pr}(IDB) = \text{Pr}(IDB \, | \, B) \cdot \text{Pr}(B) + \text{Pr}(IDB \, | \, G) \cdot \text{Pr}(G).</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">G</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal">G</span><span class="mclose">)</span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Since there is only an 80% chance of correct identification, we know that
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>G</mi><mo stretchy="false">)</mo><mo>=</mo><mn>0.2</mn></mrow><annotation encoding="application/x-tex">\text{Pr}(IDB \, | \, G) = 0.2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">G</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.2</span></span></span></span> (the probability of
misidentifying a Green cab as Blue). We also know that 85% of the cabs are
Green hence we can plug these in (along with numbers already computed) to get</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mn>0.8</mn><mo>⋅</mo><mn>0.15</mn><mo>+</mo><mn>0.2</mn><mo>⋅</mo><mn>0.85</mn><mo>=</mo><mn>0.12</mn><mo>+</mo><mn>0.17</mn><mo>=</mo><mn>0.29.</mn></mrow><annotation encoding="application/x-tex">\text{Pr}(IDB) = 0.8 \cdot 0.15 + 0.2 \cdot 0.85 = 0.12 + 0.17 = 0.29.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.8</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">0.15</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.85</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">0.12</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.17</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.29.</span></span></span></span></span>
</blockquote></div>
<p>Putting it all together we get our answer</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mtext> </mtext><mi mathvariant="normal">∣</mi><mtext> </mtext><mi>I</mi><mi>D</mi><mi>B</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>B</mi><mtext> and </mtext><mi>I</mi><mi>D</mi><mi>B</mi><mtext> both occur</mtext><mo stretchy="false">)</mo></mrow><mrow><mtext>Pr</mtext><mo stretchy="false">(</mo><mi>I</mi><mi>D</mi><mi>B</mi><mo stretchy="false">)</mo></mrow></mfrac><mo>=</mo><mfrac><mn>0.12</mn><mn>0.29</mn></mfrac><mo>≈</mo><mn>0.413793103.</mn></mrow><annotation encoding="application/x-tex">\text{Pr}(B \, | \, IDB) = \frac{\text{Pr}(B \text{ and } IDB \text{ both occur})}{\text{Pr}(IDB)} = \frac{0.12}{0.29} \approx 0.413793103.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">∣</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord text"><span class="mord">Pr</span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord text"><span class="mord"> and </span></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord text"><span class="mord"> both occur</span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0.29</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0.12</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.413793103.</span></span></span></span></span>
</blockquote></div>
<p>Fantastic! Now we can get back to reading...</p>Trigonometry and Nested Radicals2013-11-25T00:00:00-08:002013-11-25T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2013-11-25:/2013/11/trigonometry-and-nested-radicals.html<p>Early last month, I was chatting with one of my officemates about a
curious problem I had studied in high school. I hadn't written any of
the results down, so much of the discussion involved me rediscovering
the results and proving them with much more powerful tools than I once …</p><p>Early last month, I was chatting with one of my officemates about a
curious problem I had studied in high school. I hadn't written any of
the results down, so much of the discussion involved me rediscovering
the results and proving them with much more powerful tools than I once
possessed.</p>
<p>Before writing about the problem I had played around with, I want to
give a
<span style="text-decoration: line-through;">brief</span>
motivation. For as long as humans have been
doing mathematics, finding values of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>π</mi></mrow><annotation encoding="application/x-tex">\pi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span> has been deemed
worthwhile (or every generation has just found it worthwhile to waste time
computing digits).</p>
<p>One such way the Greeks (particularly
<a href="http://www.math.utah.edu/~alfeld/Archimedes/Archimedes.html">Archimedes</a>)
computed <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>π</mi></mrow><annotation encoding="application/x-tex">\pi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span> was by approximating a circle by a regular polygon
and letting the number of sides grow large enough so that the error
between the area of the unit circle <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>π</mi><mo>⋅</mo><msup><mn>1</mn><mn>2</mn></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(\pi \cdot 1^2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> and the
area of the polygon would be smaller than some fixed threshold. Usually
these thresholds were picked to ensure that the first <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> digits
were fully accurate — for some appropriate value of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>.</p>
<p>In many introductory Calculus courses, this problem is introduced
exactly when the limit is introduced and students are forced to think
about the <a href="http://www.qbyte.org/puzzles/p045s.html">area problem</a> in the
regular polygon:</p>
<div style="text-align: center;">
<p><img alt="Compute pi from polygons" src="/images/p045.png"></p>
</div>
<p>Given <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> sides, the area is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi><mo>⋅</mo><msub><mi>T</mi><mi>N</mi></msub></mrow><annotation encoding="application/x-tex">N \cdot T_N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10903em;">N</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>
where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>T</mi><mi>N</mi></msub></mrow><annotation encoding="application/x-tex">T_N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.10903em;">N</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the area of each individual triangle given by
one side of the polygon and the circumcenter.</p>
<p>Call one such triangle <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">Δ</mi><mi>A</mi><mi>B</mi><mi>C</mi></mrow><annotation encoding="application/x-tex">\Delta ABC</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord">Δ</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.07153em;">BC</span></span></span></span> and let
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi><mi>C</mi></mrow><annotation encoding="application/x-tex">BC</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">BC</span></span></span></span> be the side that is also a side of the polygon while the
other sides have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence="true">∣</mo><mi>A</mi><mi>B</mi><mo fence="true">∣</mo></mrow><mo>=</mo><mrow><mo fence="true">∣</mo><mi>A</mi><mi>C</mi><mo fence="true">∣</mo></mrow><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\left|AB\right| = \left|AC\right| = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose delimcenter" style="top:0em;">∣</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mclose delimcenter" style="top:0em;">∣</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>
since the polygon is inscribed in a unit circle. The angle
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">∠</mi><mi>B</mi><mi>A</mi><mi>C</mi><mo>=</mo><mfrac><mrow><mn>2</mn><mi>π</mi></mrow><mi>N</mi></mfrac></mrow><annotation encoding="application/x-tex">\angle BAC = \frac{2\pi}{N}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69224em;vertical-align:0em;"></span><span class="mord">∠</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10903em;">N</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">π</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> since each of the triangles
has the same internal
angle and there are <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> of them. If we can find the
perpendicular height <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span> from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mi>B</mi></mrow><annotation encoding="application/x-tex">AB</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> to
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>C</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">C,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mpunct">,</span></span></span></span> the area will be
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>h</mi><mrow><mo fence="true">∣</mo><mi>A</mi><mi>B</mi><mo fence="true">∣</mo></mrow><mo>=</mo><mfrac><mi>h</mi><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{1}{2} h \left|AB\right| = \frac{h}{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose delimcenter" style="top:0em;">∣</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2251079999999999em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8801079999999999em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">h</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>. But we also
know that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mi mathvariant="normal">∠</mi><mi>B</mi><mi>A</mi><mi>C</mi><mo fence="true">)</mo></mrow><mo>=</mo><mfrac><mi>h</mi><mrow><mo fence="true">∣</mo><mi>A</mi><mi>C</mi><mo fence="true">∣</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">\sin\left(\angle BAC\right) = \frac{h}{\left|AC\right|}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">∠</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.30744em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mclose delimcenter" style="top:0em;">∣</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">h</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>hence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>h</mi><mo>=</mo><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mrow><mn>2</mn><mi>π</mi></mrow><mi>N</mi></mfrac><mo fence="true">)</mo></mrow><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">h = \sin\left(\frac{2\pi}{N}\right).</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Combining all of these, we can approximate <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>π</mi></mrow><annotation encoding="application/x-tex">\pi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span> with
the area:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>π</mi><mo>≈</mo><mfrac><mi>N</mi><mn>2</mn></mfrac><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mrow><mn>2</mn><mi>π</mi></mrow><mi>N</mi></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mi>π</mi><mfrac><mrow><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mn>2</mn><mi>π</mi><mi mathvariant="normal">/</mi><mi>N</mi><mo fence="true">)</mo></mrow></mrow><mrow><mn>2</mn><mi>π</mi><mi mathvariant="normal">/</mi><mi>N</mi></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\pi \approx \frac{N}{2} \sin\left(\frac{2\pi}{N}\right) = \pi \frac{\sin\left(2\pi / N\right)}{2 \pi / N}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.48312em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.36033em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose delimcenter" style="top:0em;">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>As I've shown my
<a href="http://math.berkeley.edu/courses/choosing/lowerdivcourses/math1A">Math 1A</a>
students, we see that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><munder><mrow><mi>lim</mi><mo>⁡</mo></mrow><mrow><mi>N</mi><mo>→</mo><mi mathvariant="normal">∞</mi></mrow></munder><mi>π</mi><mfrac><mrow><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mn>2</mn><mi>π</mi><mi mathvariant="normal">/</mi><mi>N</mi><mo fence="true">)</mo></mrow></mrow><mrow><mn>2</mn><mi>π</mi><mi mathvariant="normal">/</mi><mi>N</mi></mrow></mfrac><mo>=</mo><mi>π</mi><munder><mrow><mi>lim</mi><mo>⁡</mo></mrow><mrow><mi>x</mi><mo>→</mo><mn>0</mn></mrow></munder><mfrac><mrow><mi>sin</mi><mo>⁡</mo><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mi>x</mi></mfrac><mo>=</mo><mi>π</mi></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle \lim_{N \to \infty} \pi \frac{\sin\left(2\pi / N\right)}{2 \pi / N} = \pi \lim_{x \to 0} \frac{\sin(x)}{x} = \pi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-2.355669em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10903em;">N</span><span class="mrel mtight">→</span><span class="mord mtight">∞</span></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop">lim</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.744331em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mclose delimcenter" style="top:0em;">)</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.144108em;vertical-align:-0.717108em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-2.382892em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="mrel mtight">→</span><span class="mord mtight">0</span></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop">lim</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.717108em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mop">sin</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span></span>
</blockquote></div>
<p>so these are indeed good approximations.</p>
<h3>Theory is Nice, But I Thought We Were Computing Something</h3>
<p>Unfortunately for us (and Archimedes), computing
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mrow><mn>2</mn><mi>π</mi></mrow><mi>N</mi></mfrac><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\sin\left(\frac{2\pi}{N}\right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.20001em;vertical-align:-0.35001em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.10903em;">N</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mathnormal mtight" style="margin-right:0.03588em;">π</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span> is not quite as simple
as dividing by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">N,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span></span></span></span> so often special values of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> were chosen. In fact, starting from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span>
and then using <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi>N</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">2N,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span></span></span></span> the areas could be computed via a special
way of averaging the previous areas. Lucky for us, such a method is equivalent
to the trusty
<a href="http://en.wikipedia.org/wiki/List_of_trigonometric_identities#Double-angle.2C_triple-angle.2C_and_half-angle_formulae">half angle identities</a>
(courtesy of
<a href="http://en.wikipedia.org/wiki/Abraham_de_Moivre">Abraham De Moivre</a>).
To keep track of these polygons with a power of two as the number of
sides, we call</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mi>n</mi></msub><mo>=</mo><mfrac><msup><mn>2</mn><mi>n</mi></msup><mn>2</mn></mfrac><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mrow><mn>2</mn><mi>π</mi></mrow><msup><mn>2</mn><mi>n</mi></msup></mfrac><mo fence="true">)</mo></mrow><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">A_n = \frac{2^n}{2} \sin\left(\frac{2\pi}{2^n}\right).</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.341392em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.590392em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Starting out with the simplest polygon, the square with
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi><mo>=</mo><msup><mn>2</mn><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">N = 2^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span> sides, we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mn>2</mn></msub><mo>=</mo><mn>2</mn><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>2</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mn>2.</mn></mrow><annotation encoding="application/x-tex">A_2 = 2 \sin\left(\frac{\pi}{2}\right) = 2.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8359999999999999em;vertical-align:-0.686em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2.</span></span></span></span></span>
</blockquote></div>
<p>Jumping to the
<a href="http://en.wikipedia.org/wiki/Octagon">octagon</a> (no not that
"<a href="https://www.google.com/search?q=%22the+octagon%22&tbm=isch">The Octagon</a>"),
we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mn>3</mn></msub><mo>=</mo><mn>4</mn><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>4</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mn>4</mn><mfrac><msqrt><mn>2</mn></msqrt><mn>2</mn></mfrac><mo>=</mo><mn>2</mn><msqrt><mn>2</mn></msqrt><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">A_3 = 4 \sin\left(\frac{\pi}{4}\right) = 4 \frac{\sqrt{2}}{2} = 2 \sqrt{2}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8359999999999999em;vertical-align:-0.686em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.27022em;vertical-align:-0.686em;"></span><span class="mord">4</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5842200000000002em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.08390500000000001em;"></span><span class="mord">2</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.956095em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.916095em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08390500000000001em;"><span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>So far, the toughest thing we've had to deal with is a
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn><msup><mn>5</mn><mo lspace="0em" rspace="0em">∘</mo></msup></mrow><annotation encoding="application/x-tex">45^{\circ}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.674115em;vertical-align:0em;"></span><span class="mord">4</span><span class="mord"><span class="mord">5</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.674115em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∘</span></span></span></span></span></span></span></span></span></span></span></span> angle and haven't yet had to lean on Abraham
(<a href="/images/abraham-de-moivre.jpg">him</a>, <a href="/images/abraham-lincoln.jpg">not him</a>)
for help. The <a href="http://en.wikipedia.org/wiki/Hexadecagon">hexadecagon</a> wants
to change that:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mn>4</mn></msub><mo>=</mo><mn>8</mn><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>8</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mn>8</mn><msqrt><mfrac><mrow><mn>1</mn><mo>−</mo><mi>cos</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>4</mn></mfrac><mo fence="true">)</mo></mrow></mrow><mn>2</mn></mfrac></msqrt><mo>=</mo><mn>8</mn><msqrt><mfrac><mrow><mn>2</mn><mo>−</mo><msqrt><mn>2</mn></msqrt></mrow><mn>4</mn></mfrac></msqrt><mo>=</mo><mn>4</mn><msqrt><mrow><mn>2</mn><mo>−</mo><msqrt><mn>2</mn></msqrt></mrow></msqrt><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">A_4 = 8 \sin\left(\frac{\pi}{8}\right) = 8 \sqrt{\frac{1 - \cos\left(\frac{\pi}{4}\right)}{2}} = 8 \sqrt{\frac{2 - \sqrt{2}}{4}} = 4 \sqrt{2 - \sqrt{2}}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8359999999999999em;vertical-align:-0.686em;"></span><span class="mord">8</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">8</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.04em;vertical-align:-0.9541200000000001em;"></span><span class="mord">8</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.08588em;"><span class="svg-align" style="top:-5em;"><span class="pstrut" style="height:5em;"></span><span class="mord" style="padding-left:1em;"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.59001em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.7400100000000003em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mop">cos</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">π</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.04588em;"><span class="pstrut" style="height:5em;"></span><span class="hide-tail" style="min-width:1.02em;height:3.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.08em' viewBox='0 0 400000 3240' preserveAspectRatio='xMinYMin slice'><path d='M473,2793
c339.3,-1799.3,509.3,-2700,510,-2702 l0 -0
c3.3,-7.3,9.3,-11,18,-11 H400000v40H1017.7
s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
606zM1001 80h400000v40H1017.7z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9541200000000001em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.04em;vertical-align:-0.9570150000000002em;"></span><span class="mord">8</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.082985em;"><span class="svg-align" style="top:-5em;"><span class="pstrut" style="height:5em;"></span><span class="mord" style="padding-left:1em;"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5842200000000002em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.042985em;"><span class="pstrut" style="height:5em;"></span><span class="hide-tail" style="min-width:1.02em;height:3.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.08em' viewBox='0 0 400000 3240' preserveAspectRatio='xMinYMin slice'><path d='M473,2793
c339.3,-1799.3,509.3,-2700,510,-2702 l0 -0
c3.3,-7.3,9.3,-11,18,-11 H400000v40H1017.7
s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
606zM1001 80h400000v40H1017.7z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9570150000000002em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8399999999999999em;vertical-align:-0.37002999999999997em;"></span><span class="mord">4</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.46997em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.956095em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.916095em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08390500000000001em;"><span></span></span></span></span></span></span></span><span style="top:-3.42997em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37002999999999997em;"><span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>To really drill home the point (and motivate my next post) we'll compute
this for the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>32</mn></mrow><annotation encoding="application/x-tex">32</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">32</span></span></span></span>-gon (past the point where polygons
have worthwhile names):</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mn>5</mn></msub><mo>=</mo><mn>16</mn><mi>sin</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>16</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mn>16</mn><msqrt><mfrac><mrow><mn>1</mn><mo>−</mo><mi>cos</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>8</mn></mfrac><mo fence="true">)</mo></mrow></mrow><mn>2</mn></mfrac></msqrt><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">A_5 = 16 \sin\left(\frac{\pi}{16}\right) = 16 \sqrt{\frac{1 - \cos\left(\frac{\pi}{8}\right)}{2}}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8359999999999999em;vertical-align:-0.686em;"></span><span class="mord">16</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mop">sin</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">16</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.04em;vertical-align:-0.9541200000000001em;"></span><span class="mord">16</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.08588em;"><span class="svg-align" style="top:-5em;"><span class="pstrut" style="height:5em;"></span><span class="mord" style="padding-left:1em;"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.59001em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.7400100000000003em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mop">cos</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">8</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">π</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.04588em;"><span class="pstrut" style="height:5em;"></span><span class="hide-tail" style="min-width:1.02em;height:3.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.08em' viewBox='0 0 400000 3240' preserveAspectRatio='xMinYMin slice'><path d='M473,2793
c339.3,-1799.3,509.3,-2700,510,-2702 l0 -0
c3.3,-7.3,9.3,-11,18,-11 H400000v40H1017.7
s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
606zM1001 80h400000v40H1017.7z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9541200000000001em;"><span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Before, we could rely on the fact that we know that a
45-45-90 triangle looked like, but now, we come across
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>cos</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>8</mn></mfrac><mo fence="true">)</mo></mrow><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\cos\left(\frac{\pi}{8}\right),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.20001em;vertical-align:-0.35001em;"></span><span class="mop">cos</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">8</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">π</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span></span></span></span> a value
which we haven't seen before. Luckily, Abraham has help here as well:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>cos</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>8</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><msqrt><mfrac><mrow><mn>1</mn><mo>+</mo><mi>cos</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mfrac><mi>π</mi><mn>4</mn></mfrac><mo fence="true">)</mo></mrow></mrow><mn>2</mn></mfrac></msqrt><mo>=</mo><msqrt><mfrac><mrow><mn>2</mn><mo>+</mo><msqrt><mn>2</mn></msqrt></mrow><mn>4</mn></mfrac></msqrt><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><msqrt><mrow><mn>2</mn><mo>+</mo><msqrt><mn>2</mn></msqrt></mrow></msqrt></mrow><annotation encoding="application/x-tex">\cos\left(\frac{\pi}{8}\right) = \sqrt{\frac{1 + \cos\left(\frac{\pi}{4}\right)}{2}} = \sqrt{\frac{2 + \sqrt{2}}{4}} = \frac{1}{2} \sqrt{2 + \sqrt{2}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.8359999999999999em;vertical-align:-0.686em;"></span><span class="mop">cos</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">8</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.04em;vertical-align:-0.9541200000000001em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.08588em;"><span class="svg-align" style="top:-5em;"><span class="pstrut" style="height:5em;"></span><span class="mord" style="padding-left:1em;"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.59001em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.7400100000000003em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mop">cos</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">4</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03588em;">π</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.04588em;"><span class="pstrut" style="height:5em;"></span><span class="hide-tail" style="min-width:1.02em;height:3.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.08em' viewBox='0 0 400000 3240' preserveAspectRatio='xMinYMin slice'><path d='M473,2793
c339.3,-1799.3,509.3,-2700,510,-2702 l0 -0
c3.3,-7.3,9.3,-11,18,-11 H400000v40H1017.7
s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
606zM1001 80h400000v40H1017.7z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9541200000000001em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.04em;vertical-align:-0.9570150000000002em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.082985em;"><span class="svg-align" style="top:-5em;"><span class="pstrut" style="height:5em;"></span><span class="mord" style="padding-left:1em;"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5842200000000002em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.042985em;"><span class="pstrut" style="height:5em;"></span><span class="hide-tail" style="min-width:1.02em;height:3.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.08em' viewBox='0 0 400000 3240' preserveAspectRatio='xMinYMin slice'><path d='M473,2793
c339.3,-1799.3,509.3,-2700,510,-2702 l0 -0
c3.3,-7.3,9.3,-11,18,-11 H400000v40H1017.7
s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
606zM1001 80h400000v40H1017.7z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9570150000000002em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.15597em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.46997em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.956095em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.916095em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08390500000000001em;"><span></span></span></span></span></span></span></span><span style="top:-3.42997em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37002999999999997em;"><span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>which lets us compute</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mn>5</mn></msub><mo>=</mo><mn>16</mn><msqrt><mfrac><mrow><mn>1</mn><mo>−</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><msqrt><mrow><mn>2</mn><mo>+</mo><msqrt><mn>2</mn></msqrt></mrow></msqrt></mrow><mn>2</mn></mfrac></msqrt><mo>=</mo><mn>8</mn><msqrt><mrow><mn>2</mn><mo>−</mo><msqrt><mrow><mn>2</mn><mo>+</mo><msqrt><mn>2</mn></msqrt></mrow></msqrt></mrow></msqrt><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">A_5 = 16 \sqrt{\frac{1 - \frac{1}{2} \sqrt{2 + \sqrt{2}}}{2}} = 8 \sqrt{2 - \sqrt{2 + \sqrt{2}}}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.04em;vertical-align:-0.8455149999999998em;"></span><span class="mord">16</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.1944850000000002em;"><span class="svg-align" style="top:-5em;"><span class="pstrut" style="height:5em;"></span><span class="mord" style="padding-left:1em;"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.80722em;"><span style="top:-2.3862200000000002em;"><span class="pstrut" style="height:3.07222em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.30222em;"><span class="pstrut" style="height:3.07222em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.80722em;"><span class="pstrut" style="height:3.07222em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0722200000000002em;"><span class="svg-align" style="top:-3.2em;"><span class="pstrut" style="height:3.2em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span></span></span><span style="top:-3.03222em;"><span class="pstrut" style="height:3.2em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.28em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.28em' viewBox='0 0 400000 1296' preserveAspectRatio='xMinYMin slice'><path d='M263,681c0.7,0,18,39.7,52,119
c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120
c340,-704.7,510.7,-1060.3,512,-1067
l0 -0
c4.7,-7.3,11,-11,19,-11
H40000v40H1012.3
s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232
c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1
s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26
c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.16777999999999993em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.154485em;"><span class="pstrut" style="height:5em;"></span><span class="hide-tail" style="min-width:1.02em;height:3.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.08em' viewBox='0 0 400000 3240' preserveAspectRatio='xMinYMin slice'><path d='M473,2793
c339.3,-1799.3,509.3,-2700,510,-2702 l0 -0
c3.3,-7.3,9.3,-11,18,-11 H400000v40H1017.7
s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
606zM1001 80h400000v40H1017.7z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8455149999999998em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.44em;vertical-align:-0.556155em;"></span><span class="mord">8</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.883845em;"><span class="svg-align" style="top:-4.4em;"><span class="pstrut" style="height:4.4em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.46997em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.956095em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.916095em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08390500000000001em;"><span></span></span></span></span></span></span></span><span style="top:-3.42997em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37002999999999997em;"><span></span></span></span></span></span></span></span><span style="top:-3.8438450000000004em;"><span class="pstrut" style="height:4.4em;"></span><span class="hide-tail" style="min-width:1.02em;height:2.48em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='2.48em' viewBox='0 0 400000 2592' preserveAspectRatio='xMinYMin slice'><path d='M424,2478
c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514
c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20
s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121
s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081
l0 -0c4,-6.7,10,-10,18,-10 H400000
v40H1014.6
s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185
c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2z M1001 80
h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.556155em;"><span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>So why have I put you through all this? If we wave our hands like a
<a href="/images/magician.jpg">magician</a>,
we can see this pattern continues and for the general <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span></p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mi>n</mi></msub><mo>=</mo><msup><mn>2</mn><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msup><msqrt><mrow><mn>2</mn><mo>−</mo><msqrt><mrow><mn>2</mn><mo>+</mo><msqrt><mrow><mn>2</mn><mo>+</mo><msqrt><mrow><mo>⋯</mo><mo>+</mo><msqrt><mn>2</mn></msqrt></mrow></msqrt></mrow></msqrt></mrow></msqrt></mrow></msqrt></mrow><annotation encoding="application/x-tex">A_n = 2^{n - 2} \sqrt{2 - \sqrt{2 + \sqrt{2 + \sqrt{\cdots + \sqrt{2}}}}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.26775em;vertical-align:-0.74228em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.52547em;"><span class="svg-align" style="top:-5.22775em;"><span class="pstrut" style="height:5.22775em;"></span><span class="mord" style="padding-left:1.056em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.29772em;"><span class="svg-align" style="top:-5em;"><span class="pstrut" style="height:5em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.883845em;"><span class="svg-align" style="top:-4.4em;"><span class="pstrut" style="height:4.4em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.46997em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="minner">⋯</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.956095em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.916095em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08390500000000001em;"><span></span></span></span></span></span></span></span><span style="top:-3.42997em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.37002999999999997em;"><span></span></span></span></span></span></span></span><span style="top:-3.8438450000000004em;"><span class="pstrut" style="height:4.4em;"></span><span class="hide-tail" style="min-width:1.02em;height:2.48em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='2.48em' viewBox='0 0 400000 2592' preserveAspectRatio='xMinYMin slice'><path d='M424,2478
c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514
c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20
s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121
s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081
l0 -0c4,-6.7,10,-10,18,-10 H400000
v40H1014.6
s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185
c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2z M1001 80
h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.556155em;"><span></span></span></span></span></span></span></span><span style="top:-4.25772em;"><span class="pstrut" style="height:5em;"></span><span class="hide-tail" style="min-width:1.02em;height:3.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.08em' viewBox='0 0 400000 3240' preserveAspectRatio='xMinYMin slice'><path d='M473,2793
c339.3,-1799.3,509.3,-2700,510,-2702 l0 -0
c3.3,-7.3,9.3,-11,18,-11 H400000v40H1017.7
s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
606zM1001 80h400000v40H1017.7z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.74228em;"><span></span></span></span></span></span></span></span><span style="top:-4.48547em;"><span class="pstrut" style="height:5.22775em;"></span><span class="hide-tail" style="min-width:0.742em;height:3.30775em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.30775em' viewBox='0 0 400000 3307' preserveAspectRatio='xMinYMin slice'><path d='M702 80H40000040
H742v3173l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1
h-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170
c-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667
219 661 l218 661zM702 80H400000v40H742z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.74228em;"><span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>where there are <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>−</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">n - 3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span> nested radicals with the
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>⊕</mo></mrow><annotation encoding="application/x-tex">\oplus</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">⊕</span></span></span></span> sign and only one minus sign at the beginning.</p>
<p>This motivates us to study two questions, what is the limiting behavior
of such a nested radical:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msqrt><mrow><mn>2</mn><mo>+</mo><msub><mi>s</mi><mn>1</mn></msub><msqrt><mrow><mn>2</mn><mo>+</mo><msub><mi>s</mi><mn>2</mn></msub><msqrt><mo lspace="0em" rspace="0em">⋯</mo></msqrt></mrow></msqrt></mrow></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{2 + s_1 \sqrt{2 + s_2 \sqrt{ \cdots }}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.44em;vertical-align:-0.7218749999999998em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7181250000000001em;"><span class="svg-align" style="top:-4.4em;"><span class="pstrut" style="height:4.4em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">s</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3042500000000001em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">s</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.790375em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="minner">⋯</span></span></span><span style="top:-2.750375em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24962500000000004em;"><span></span></span></span></span></span></span></span><span style="top:-3.2642499999999997em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.53575em;"><span></span></span></span></span></span></span></span><span style="top:-3.6781250000000005em;"><span class="pstrut" style="height:4.4em;"></span><span class="hide-tail" style="min-width:1.02em;height:2.48em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='2.48em' viewBox='0 0 400000 2592' preserveAspectRatio='xMinYMin slice'><path d='M424,2478
c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514
c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20
s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121
s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081
l0 -0c4,-6.7,10,-10,18,-10 H400000
v40H1014.6
s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185
c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2z M1001 80
h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7218749999999998em;"><span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>as the signs <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>s</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>s</mi><mn>2</mn></msub><mo separator="true">,</mo><mo>…</mo></mrow><annotation encoding="application/x-tex">s_1, s_2, \ldots</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">s</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">s</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span></span></span></span> take values in
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><mo>−</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">\left\{-1, 1\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord">−</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span>. Recasting in terms of the
discussion above, we want to know how close we are to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>π</mi></mrow><annotation encoding="application/x-tex">\pi</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">π</span></span></span></span>
as we increase the number of sides.</p>
<p>When I was in high school, I just loved to
<a href="/images/nerd-out.jpg">nerd out</a>
on any and all math problems, so I studied this just for fun. Having heard
about the unfathomable brain of
<a href="http://en.wikipedia.org/wiki/Srinivasa_Ramanujan">Ramanujan</a> and the
fun
<a href="http://www.isibang.ac.in/~sury/ramanujanday.pdf">work he had done</a>
with infinitely
<a href="http://en.wikipedia.org/wiki/Nested_radical">nested radicals</a>,
I wanted to examine which sequences of signs</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><msub><mi>s</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>s</mi><mn>2</mn></msub><mo separator="true">,</mo><mo>…</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(s_1, s_2, \ldots)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">s</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">s</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mclose">)</span></span></span></span></span>
</blockquote></div>
<p>produced an infinite radical that converged and what the convergence
behavior was.</p>
<p>I'm fairly certain my original questions came from an Illinois Council
of Teachers of Mathematics (<a href="http://www.ictm.org/contest.html">ICTM</a>)
contest problem along the lines of</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Find the value of the infinite nested radical </mtext><msqrt><mrow><mn>2</mn><mo>+</mo><msqrt><mrow><mn>2</mn><mo>+</mo><mo>⋯</mo></mrow></msqrt></mrow></msqrt></mrow><annotation encoding="application/x-tex">\text{Find the value of the infinite nested radical } \sqrt{2 + \sqrt{2 + \cdots}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.84em;vertical-align:-0.4116949999999999em;"></span><span class="mord text"><span class="mord">Find the value of the infinite nested radical </span></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.4283050000000002em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9144300000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner">⋯</span></span></span><span style="top:-2.8744300000000003em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.12556999999999996em;"><span></span></span></span></span></span></span></span><span style="top:-3.388305em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4116949999999999em;"><span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>or maybe the slightly more difficult</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msqrt><mrow><mn>2</mn><mo>−</mo><msqrt><mrow><mn>2</mn><mo>+</mo><msqrt><mrow><mn>2</mn><mo>−</mo><msqrt><mrow><mn>2</mn><mo>+</mo><mo>⋯</mo></mrow></msqrt></mrow></msqrt></mrow></msqrt></mrow></msqrt><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\sqrt{2 -\sqrt{2 + \sqrt{2 -\sqrt{2 +\cdots}}}}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.04em;vertical-align:-0.7839449999999999em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.256055em;"><span class="svg-align" style="top:-5em;"><span class="pstrut" style="height:5em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.8421800000000002em;"><span class="svg-align" style="top:-4.4em;"><span class="pstrut" style="height:4.4em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.4283050000000002em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9144300000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner">⋯</span></span></span><span style="top:-2.8744300000000003em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.12556999999999996em;"><span></span></span></span></span></span></span></span><span style="top:-3.388305em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.4116949999999999em;"><span></span></span></span></span></span></span></span><span style="top:-3.802180000000001em;"><span class="pstrut" style="height:4.4em;"></span><span class="hide-tail" style="min-width:1.02em;height:2.48em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='2.48em' viewBox='0 0 400000 2592' preserveAspectRatio='xMinYMin slice'><path d='M424,2478
c-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514
c0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20
s-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121
s209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081
l0 -0c4,-6.7,10,-10,18,-10 H400000
v40H1014.6
s-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185
c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2z M1001 80
h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5978199999999998em;"><span></span></span></span></span></span></span></span><span style="top:-4.216055em;"><span class="pstrut" style="height:5em;"></span><span class="hide-tail" style="min-width:1.02em;height:3.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='3.08em' viewBox='0 0 400000 3240' preserveAspectRatio='xMinYMin slice'><path d='M473,2793
c339.3,-1799.3,509.3,-2700,510,-2702 l0 -0
c3.3,-7.3,9.3,-11,18,-11 H400000v40H1017.7
s-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9
c-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200
c0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26
s76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,
606zM1001 80h400000v40H1017.7z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7839449999999999em;"><span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Armed with my <a href="/images/TI-83.png">TI-83</a>,
I set out to do some hardcore programming and figure it out. It took me
around a month of off-and-on tinkering. This second time around as a
mathematical grown-up, it took me the first half of a plane ride from
SFO to Dallas.</p>
<p>In the next few weeks/months, I hope to write a few blog posts,
including math, proofs and some real code on what answers I came up with
and what other questions I have.</p>Calculating a Greatest Common Divisor with Dirichlet's Help2013-09-10T00:00:00-07:002013-09-10T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2013-09-10:/2013/09/calculating-greatest-common-divisor.html<p>Having just left Google and started my PhD in Applied Mathematics at
<a href="http://math.berkeley.edu/">Berkeley</a>, I thought it might be
appropriate to write some (more) math-related blog posts. Many of these
posts, I jotted down on napkins and various other places on the web and
just haven't had time to post until …</p><p>Having just left Google and started my PhD in Applied Mathematics at
<a href="http://math.berkeley.edu/">Berkeley</a>, I thought it might be
appropriate to write some (more) math-related blog posts. Many of these
posts, I jotted down on napkins and various other places on the web and
just haven't had time to post until now.</p>
<p>For today, I'm posting a result which was somewhat fun to figure out
with/for one of my
<a href="https://picasaweb.google.com/101796704659729637490/WhereHasYourMathTShirtBeen#5802889644579484306">buddies</a>
from <a href="http://www.lsa.umich.edu/math/">Michigan Math</a>. I'd also like to point
out that he is absolutely kicking ass at Brown.</p>
<p>He was trying to determine if</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>J</mi><mo stretchy="false">(</mo><msub><mi>B</mi><mi>n</mi></msub><msub><mo stretchy="false">)</mo><mtext>Tor</mtext></msub><mrow><mo fence="true">(</mo><mi mathvariant="double-struck">Q</mi><mo fence="true">)</mo></mrow><mo><mover><mo><mo>=</mo></mo><mo stretchy="false" lspace="0em" rspace="0em">?</mo></mover></mo><mi mathvariant="double-struck">Z</mi><mi mathvariant="normal">/</mi><mn>2</mn><mi mathvariant="double-struck">Z</mi><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">J(B_n)_{\text{Tor}}\left(\mathbb{Q}\right) \stackrel{?}{=} \mathbb{Z}/2\mathbb{Z}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.402978em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.09618em;">J</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.05017em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord text mtight"><span class="mord mtight">Tor</span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord mathbb">Q</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><span class="mop op-limits"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.152978em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop">=</span></span></span><span style="top:-3.5668699999999998em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mclose mtight">?</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathbb">Z</span><span class="mord">/2</span><span class="mord mathbb">Z</span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>WAT? In the above, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>J</mi><mo stretchy="false">(</mo><msub><mi>B</mi><mi>n</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">J(B_n)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.09618em;">J</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.05017em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> is the Jacobian of the
curve <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>B</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">B_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.05017em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> given by
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>y</mi><mn>2</mn></msup><mo>=</mo><mo stretchy="false">(</mo><mi>x</mi><mo>+</mo><mn>2</mn><mo stretchy="false">)</mo><mo>⋅</mo><msup><mi>f</mi><mi>n</mi></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">y^2 = (x + 2) \cdot f^n(x)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.008548em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span>. Here
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mi>n</mi></msup></mrow><annotation encoding="application/x-tex">f^n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span> denotes</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><munder><munder><mrow><mi>f</mi><mo>∘</mo><mo>⋯</mo><mo>∘</mo><mi>f</mi></mrow><mo stretchy="true">⏟</mo></munder><mrow><mi>n</mi><mtext> times</mtext></mrow></munder></mrow><annotation encoding="application/x-tex">\underbrace{f \circ \cdots \circ f}_{n \text{ times}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.204382em;vertical-align:-1.5099420000000001em;"></span><span class="mord munder"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-1.4900579999999999em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mord text mtight"><span class="mord mtight"> times</span></span></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord munder"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.6944399999999998em;"><span class="svg-align" style="top:-2.15756em;"><span class="pstrut" style="height:3em;"></span><span class="stretchy" style="height:0.548em;min-width:1.6em;"><span class="brace-left" style="height:0.548em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='0.548em' viewBox='0 0 400000 548' preserveAspectRatio='xMinYMin slice'><path d='M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13
35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688
0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7
-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z'/></svg></span><span class="brace-center" style="height:0.548em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='0.548em' viewBox='0 0 400000 548' preserveAspectRatio='xMidYMin slice'><path d='M199572 214
c100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14
53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3
11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0
-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z'/></svg></span><span class="brace-right" style="height:0.548em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='0.548em' viewBox='0 0 400000 548' preserveAspectRatio='xMaxYMin slice'><path d='M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3
28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237
-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z'/></svg></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">∘</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner">⋯</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">∘</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8424400000000001em;"><span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5099420000000001em;"><span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">f(x) = x^2 - 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>.</p>
<p>Now, his and my interests diverged some time ago, so I can't appreciate
what steps took him from this to the problem I got to help with.
However, he was able to show (trivially maybe?) that this was equivalent
to showing that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>gcd</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><msup><mn>5</mn><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><msup><mn>3</mn><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo separator="true">,</mo><mo>…</mo><mo separator="true">,</mo><msup><mi>p</mi><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo separator="true">,</mo><mo>…</mo><mo fence="true">)</mo></mrow><mo>=</mo><mn>2</mn><mspace width="2em"/><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\gcd\left(5^{2^n} + 1, 13^{2^n} + 1, \ldots, p^{2^n} + 1, \ldots \right) = 2 \qquad (1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.80002em;vertical-align:-0.65002em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mord">5</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord"><span class="mord">3</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:2em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span></span></span></span></span>
</blockquote></div>
<p>where the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> in the exponents is the same as that in
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>B</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">B_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.05017em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and where the values we are using in our greatest common
divisor (e.g. <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><mo separator="true">,</mo><mn>13</mn></mrow><annotation encoding="application/x-tex">5, 13</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">5</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">13</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span></span></span></span> above) are all
of the primes <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo>≡</mo><mn>5</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mn>8</mn></mrow><annotation encoding="application/x-tex">p \equiv 5 \bmod{8}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65819em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">5</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord"><span class="mord">8</span></span></span></span></span>.</p>
<p>My buddy, being sadistic and for some reason angry with me, passed me
along the stronger statement:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>gcd</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><msup><mn>5</mn><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><msup><mn>3</mn><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo fence="true">)</mo></mrow><mo>=</mo><mn>2</mn><mspace width="2em"/><mo stretchy="false">(</mo><mn>2</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\gcd\left(5^{2^n} + 1, 13^{2^n} + 1\right) = 2 \qquad (2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.80002em;vertical-align:-0.65002em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mord">5</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord"><span class="mord">3</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:2em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mclose">)</span></span></span></span></span>
</blockquote></div>
<p>which I of course struggled with and tried to beat down with tricks like
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>5</mn><mn>2</mn></msup><mo>+</mo><mn>1</mn><msup><mn>2</mn><mn>2</mn></msup><mo>=</mo><mn>1</mn><msup><mn>3</mn><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">5^2 + 12^2 = 13^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">5</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord">1</span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord">1</span><span class="mord"><span class="mord">3</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>. After a few days of this struggle, he
confessed that he was trying to ruin my life and told me about the
weaker version <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span></span></span></span>.</p>
<p>When he sent me the email informing me of this, I read it at 8am, drove
down to Santa Clara for <a href="https://us.pycon.org/2013/">PyCon</a> and by the
time I arrived at 8:45am I had figured the weaker case <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span></span></span></span>
out. This felt much better than the days of struggle and made me want to
write about my victory (which I'm doing now). Though, before we actually
demonstrate the weaker fact <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span></span></span></span> I will admit that I am not in
fact tall. Instead I stood on the shoulders of Dirichlet and
<a href="http://www.youtube.com/watch?v=A6f-6l0W-0o#t=35s">called myself tall</a>.
Everything else is bookkeeping.</p>
<h2>Let's Start the Math</h2>
<p>First, if <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>0</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">n = 0,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mpunct">,</span></span></span></span> we see trivially that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>gcd</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><msup><mn>5</mn><msup><mn>2</mn><mn>0</mn></msup></msup><mo>+</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><msup><mn>3</mn><msup><mn>2</mn><mn>0</mn></msup></msup><mo>+</mo><mn>1</mn><mo fence="true">)</mo></mrow><mo>=</mo><mi>gcd</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><mn>6</mn><mo separator="true">,</mo><mn>14</mn><mo fence="true">)</mo></mrow><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">\gcd\left(5^{2^0} + 1, 13^{2^0} + 1\right) = \gcd\left(6, 14\right) = 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.80002em;vertical-align:-0.65002em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mord">5</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0369199999999998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord"><span class="mord">3</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0369199999999998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">0</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">6</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">14</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span></span>
</blockquote></div>
<p>and all the remaining terms are divisible by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span> hence the
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>gcd</mi><mo>⁡</mo></mrow><annotation encoding="application/x-tex">\gcd</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span></span></span></span> over all the primes must be <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>.</p>
<p>Now, if <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>></mo><mn>0</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">n > 0,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mpunct">,</span></span></span></span> we will show that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span> divides
our <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>gcd</mi><mo>⁡</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\gcd,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span><span class="mpunct">,</span></span></span></span> but <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn></mrow><annotation encoding="application/x-tex">4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span> does not and that no odd
prime can divide this <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>gcd</mi><mo>⁡</mo></mrow><annotation encoding="application/x-tex">\gcd</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span></span></span></span>. First, for
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">2</span><span class="mpunct">,</span></span></span></span> note that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>p</mi><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo>≡</mo><msup><mrow><mo fence="true">(</mo><mo>±</mo><mn>1</mn><mo fence="true">)</mo></mrow><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo>≡</mo><mn>2</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mn>4</mn></mrow><annotation encoding="application/x-tex">p^{2^n} + 1 \equiv \left(\pm 1\right)^{2^n} + 1 \equiv 2 \bmod{4}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.12442em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2698800000000001em;vertical-align:-0.25em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">±</span><span class="mord">1</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0198800000000001em;"><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord"><span class="mord">4</span></span></span></span></span></span>
</blockquote></div>
<p>since our primes are odd. Thus they are all divisible by
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span> and none by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn></mrow><annotation encoding="application/x-tex">4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span>.</p>
<p>Now assume some odd prime <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">p^{*}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span> divides all of the quantities
in question. We'll show no such <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">p^{*}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span> can exist by
contradiction.</p>
<p>In much the same way we showed the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>gcd</mi><mo>⁡</mo></mrow><annotation encoding="application/x-tex">\gcd</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span></span></span></span> wasn't divisible by
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">4,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">4</span><span class="mpunct">,</span></span></span></span> we seek to find a contradiction in some modulus. But since
we are starting with</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>p</mi><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo>≡</mo><mn>0</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">p^{2^n} + 1 \equiv 0 \bmod{p^{\ast}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.12442em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.933136em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>if we can find some such <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span></span></span></span> with</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>p</mi><mo>≡</mo><mn>1</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">p \equiv 1 \bmod{p^{\ast}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65819em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.933136em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>then we'd have our contradiction from</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>0</mn><mo>≡</mo><msup><mi>p</mi><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo>≡</mo><msup><mn>1</mn><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo>≡</mo><mn>2</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">0 \equiv p^{2^n} + 1 \equiv 1^{2^n} + 1 \equiv 2 \bmod{p^{\ast}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.12442em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.01331em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.933136em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>which can't occur since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">p^{*}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span> is an odd prime.</p>
<p>With this in mind, along with a subsequence of the arithmetic
progression <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo fence="true">{</mo><mn>5</mn><mo separator="true">,</mo><mn>13</mn><mo separator="true">,</mo><mn>21</mn><mo separator="true">,</mo><mn>29</mn><mo separator="true">,</mo><mo>…</mo><mo fence="true">}</mo></mrow><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\left\{5, 13, 21, 29, \ldots\right\},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord">5</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">13</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">21</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">29</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span></span></span></span> it
seems that using
<a href="http://en.wikipedia.org/wiki/Dirichlet%27s_theorem_on_arithmetic_progressions">Dirichlet's theorem on arithmetic progressions</a>
may be a good strategy. However, this sequence only tells us about the
residue modulo <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>8</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">8,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">8</span><span class="mpunct">,</span></span></span></span> but we also want to know about the residue
modulo <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">p^{*}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span>. Naturally, we look for a subsequence in</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi mathvariant="double-struck">Z</mi><mi mathvariant="normal">/</mi><mn>8</mn><mi mathvariant="double-struck">Z</mi><mo>×</mo><mi mathvariant="double-struck">Z</mi><mi mathvariant="normal">/</mi><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mi mathvariant="double-struck">Z</mi></mrow><annotation encoding="application/x-tex">\mathbb{Z}/8\mathbb{Z} \times \mathbb{Z}/p^{*}\mathbb{Z}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathbb">Z</span><span class="mord">/8</span><span class="mord mathbb">Z</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathbb">Z</span><span class="mord">/</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mord mathbb">Z</span></span></span></span></span>
</blockquote></div>
<p>corresponding to the residue pair
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>5</mn><mtext> mod </mtext><mn>8</mn><mo separator="true">,</mo><mn>1</mn><mtext> mod </mtext><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(5 \text{ mod }{8}, 1 \text{ mod }{p^{*}} )</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">5</span><span class="mord text"><span class="mord"> mod </span></span><span class="mord"><span class="mord">8</span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord text"><span class="mord"> mod </span></span><span class="mord"><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span>. Due to the
<a href="http://en.wikipedia.org/wiki/Chinese_remainder_theorem">Chinese remainder theorem</a>
this corresponds to a unique residue modulo <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>8</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">8p^{*}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord">8</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span>.</p>
<p>Since this residue <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi></mrow><annotation encoding="application/x-tex">r</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span> has
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi><mo>≡</mo><mn>1</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">r \equiv 1 \bmod{p^{\ast}} ,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> we must have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>r</mi><mo>∈</mo><mrow><mo fence="true">{</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><mo>+</mo><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo separator="true">,</mo><mn>1</mn><mo>+</mo><mn>2</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo separator="true">,</mo><mo>…</mo><mo separator="true">,</mo><mn>1</mn><mo>+</mo><mn>7</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo fence="true">}</mo></mrow><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">r \in \left\{1, 1 + p^{*}, 1 + 2p^{*}, \ldots, 1 + 7p^{*}\right\}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">7</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>But since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>+</mo><mi>k</mi><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo>≡</mo><mi>r</mi><mo>≡</mo><mn>5</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mn>8</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">1 + kp^{\ast} \equiv r \equiv 5 \bmod{8},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.46375em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">5</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord">8</span></span><span class="mpunct">,</span></span></span></span>
we have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo>≡</mo><mn>4</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mn>8</mn></mrow><annotation encoding="application/x-tex">kp^{\ast} \equiv 4 \bmod{8}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord"><span class="mord">8</span></span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>=</mo><mn>4</mn><msup><mrow><mo fence="true">(</mo><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo fence="true">)</mo></mrow><mrow><mo>−</mo><mn>1</mn></mrow></msup><mtext> mod </mtext><mn>8</mn></mrow><annotation encoding="application/x-tex">k = 4\left(p^{*}\right)^{-1} \text{ mod }{8}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.204008em;vertical-align:-0.25em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.954008em;"><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord text"><span class="mord"> mod </span></span><span class="mord"><span class="mord">8</span></span></span></span></span> since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">p^{*}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span> is odd and invertible mod <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>8</mn></mrow><annotation encoding="application/x-tex">8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">8</span></span></span></span>. But
this also means its inverse is odd, hence
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>≡</mo><mn>4</mn><mo>⋅</mo><mo stretchy="false">(</mo><mn>2</mn><msup><mi>k</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>≡</mo><mn>4</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mn>8</mn></mrow><annotation encoding="application/x-tex">k \equiv 4\cdot(2k' + 1) \equiv 4 \bmod{8}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord"><span class="mord">8</span></span></span></span></span>. Thus
we have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>+</mo><mn>4</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo>∈</mo><mi mathvariant="double-struck">Z</mi><mi mathvariant="normal">/</mi><mn>8</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mi mathvariant="double-struck">Z</mi></mrow><annotation encoding="application/x-tex">1 + 4 p^{\ast} \in \mathbb{Z}/8p^{\ast}\mathbb{Z}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathbb">Z</span><span class="mord">/8</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mord mathbb">Z</span></span></span></span>
corresponding to our residue pair. Thus every element in the arithmetic
progression</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><mi>S</mi><mo>=</mo><msubsup><mrow><mo fence="true">{</mo><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><mn>4</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo stretchy="false">)</mo><mo>+</mo><mo stretchy="false">(</mo><mn>8</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo stretchy="false">)</mo><mi>k</mi><mo fence="true">}</mo></mrow><mrow><mi>k</mi><mo>=</mo><mn>0</mn></mrow><mi mathvariant="normal">∞</mi></msubsup></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle S = \left\{(1 + 4p^{*}) + (8p^{*})k \right\}_{k=0}^{\infty}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.1039919999999999em;vertical-align:-0.29969999999999997em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord">8</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.804292em;"><span style="top:-2.4003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mrel mtight">=</span><span class="mord mtight">0</span></span></span></span><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∞</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.29969999999999997em;"><span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>is congruent to
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>+</mo><mn>4</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mtext> mod </mtext><mrow><mn>8</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow></mrow><annotation encoding="application/x-tex">1 + 4 p^{*} \text{ mod }{8p^{*}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mord text"><span class="mord"> mod </span></span><span class="mord"><span class="mord">8</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span></span> and hence
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><mtext> mod </mtext><mn>8</mn></mrow><annotation encoding="application/x-tex">5 \text{ mod }{8}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">5</span><span class="mord text"><span class="mord"> mod </span></span><span class="mord"><span class="mord">8</span></span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mtext> mod </mtext><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">1 \text{ mod }{p^{*}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mord text"><span class="mord"> mod </span></span><span class="mord"><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span></span>.</p>
<p>What's more, since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><mo>∈</mo><msup><mrow><mo fence="true">(</mo><mi mathvariant="double-struck">Z</mi><mi mathvariant="normal">/</mi><mn>8</mn><mi mathvariant="double-struck">Z</mi><mo fence="true">)</mo></mrow><mo lspace="0em" rspace="0em">×</mo></msup></mrow><annotation encoding="application/x-tex">5 \in \left(\mathbb{Z}/8\mathbb{Z}\right)^{\times}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68354em;vertical-align:-0.0391em;"></span><span class="mord">5</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.161231em;vertical-align:-0.25em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord mathbb">Z</span><span class="mord">/8</span><span class="mord mathbb">Z</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.911231em;"><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">×</span></span></span></span></span></span></span></span></span></span></span></span>
and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>∈</mo><msup><mrow><mo fence="true">(</mo><mi mathvariant="double-struck">Z</mi><mi mathvariant="normal">/</mi><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mi mathvariant="double-struck">Z</mi><mo fence="true">)</mo></mrow><mo lspace="0em" rspace="0em">×</mo></msup><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">1 \in \left(\mathbb{Z}/p^{*}\mathbb{Z}\right)^{\times},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68354em;vertical-align:-0.0391em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.161231em;vertical-align:-0.25em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord mathbb">Z</span><span class="mord">/</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mord mathbb">Z</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.911231em;"><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">×</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span></span></span></span>
we have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>+</mo><mn>4</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo>∈</mo><msup><mrow><mo fence="true">(</mo><mi mathvariant="double-struck">Z</mi><mi mathvariant="normal">/</mi><mn>8</mn><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mi mathvariant="double-struck">Z</mi><mo fence="true">)</mo></mrow><mo lspace="0em" rspace="0em">×</mo></msup></mrow><annotation encoding="application/x-tex">1 + 4 p^{*} \in \left(\mathbb{Z}/8p^{*}\mathbb{Z}\right)^{\times}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.161231em;vertical-align:-0.25em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord mathbb">Z</span><span class="mord">/8</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mord mathbb">Z</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.911231em;"><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">×</span></span></span></span></span></span></span></span></span></span></span></span>
(again by the Chinese remainder theorem). Thus the arithmetic progression
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>S</mi></mrow><annotation encoding="application/x-tex">S</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span></span></span></span> satisfies the hypothesis of Dirichlet's theorem. Hence
there must be at least one prime <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span></span></span></span> occurring in the
progression (since there are infinitely many). But that also means
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span></span></span></span> occurs in
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><mn>5</mn><mo separator="true">,</mo><mn>13</mn><mo separator="true">,</mo><mn>29</mn><mo separator="true">,</mo><mn>37</mn><mo separator="true">,</mo><mo>…</mo><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">\left\{5, 13, 29, 37, \ldots\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord">5</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">13</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">29</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">37</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span> hence
we've reached our desired contradiction. RAA.</p>
<h2>Now What</h2>
<p>We still
<a href="http://math.stackexchange.com/q/659193/31956">don't know</a>
if the strong version <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>2</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mclose">)</span></span></span></span></p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>gcd</mi><mo>⁡</mo><mrow><mo fence="true">(</mo><msup><mn>5</mn><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><msup><mn>3</mn><msup><mn>2</mn><mi>n</mi></msup></msup><mo>+</mo><mn>1</mn><mo fence="true">)</mo></mrow><mo>=</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">\gcd\left(5^{2^n} + 1, 13^{2^n} + 1\right) = 2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.80002em;vertical-align:-0.65002em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mord">5</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mord"><span class="mord">3</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span></span>
</blockquote></div>
<p>By similar arguments as above, if any odd prime
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">p^{*}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span> divides this <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>gcd</mi><mo>⁡</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\gcd,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mop"><span style="margin-right:0.01389em;">g</span>cd</span><span class="mpunct">,</span></span></span></span> then we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mn>5</mn><msup><mn>2</mn><mi>n</mi></msup></msup><mo>≡</mo><mo>−</mo><mn>1</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup></mrow><annotation encoding="application/x-tex">5^{2^n} \equiv -1 \bmod{p^{\ast}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.92998em;vertical-align:0em;"></span><span class="mord"><span class="mord">5</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.92998em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7385428571428572em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord">1</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.933136em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.738696em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>hence there is an element
of order <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">2^{n+ 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>. This means the order of the multiplicative
group <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>φ</mi><mrow><mo fence="true">(</mo><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo fence="true">)</mo></mrow><mo>=</mo><msup><mi>p</mi><mo lspace="0em" rspace="0em">∗</mo></msup><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\varphi\left(p^{*}\right) = p^{*} - 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">φ</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8831359999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.688696em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">∗</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> is
divisible by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">2^{n + 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span>. Beyond that, who knows? We're still
thinking about it (but only passively, more important things to do).</p>Some Fibonacci Fun with Primes2013-08-18T00:00:00-07:002013-08-18T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2013-08-18:/2013/08/some-fibonacci-fun-with-primes.html<p>I haven't written in way too long and just wanted to post this fun
little proof.</p>
<p><strong>Assertion:</strong> Let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">F_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> be the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span>th
Fibonacci number defined by</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>F</mi><mi>n</mi></msub><mo>=</mo><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub><mo separator="true">,</mo><mspace width="1em"/><msub><mi>F</mi><mn>0</mn></msub><mo>=</mo><mn>0</mn><mo separator="true">,</mo><msub><mi>F</mi><mn>1</mn></msub><mo>=</mo><mn>1.</mn></mrow><annotation encoding="application/x-tex">F_n = F_{n-1 …</annotation></semantics></math></span></span></span></blockquote></div><p>I haven't written in way too long and just wanted to post this fun
little proof.</p>
<p><strong>Assertion:</strong> Let <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">F_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> be the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span>th
Fibonacci number defined by</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>F</mi><mi>n</mi></msub><mo>=</mo><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub><mo separator="true">,</mo><mspace width="1em"/><msub><mi>F</mi><mn>0</mn></msub><mo>=</mo><mn>0</mn><mo separator="true">,</mo><msub><mi>F</mi><mn>1</mn></msub><mo>=</mo><mn>1.</mn></mrow><annotation encoding="application/x-tex">F_n = F_{n-1} + F_{n-2}, \quad F_0 = 0, F_1 = 1.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.891661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.891661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1.</span></span></span></span></span>
</blockquote></div>
<p>Show that for an odd prime <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo mathvariant="normal">≠</mo><mn>5</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">p \neq 5,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="inner"><span class="mord"><span class="mrel"></span></span></span><span class="fix"></span></span></span></span></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">5</span><span class="mpunct">,</span></span></span></span> we have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span></span></span></span> divides <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">F_{p^2 - 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.997058em;vertical-align:-0.313728em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.52238em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.313728em;"><span></span></span></span></span></span></span></span></span></span>.</p>
<p><strong>Proof:</strong> We do this by working inside <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi mathvariant="double-struck">F</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">\mathbb{F}_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.974998em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>
instead of working in <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="double-struck">R</mi></mrow><annotation encoding="application/x-tex">\mathbb{R}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68889em;vertical-align:0em;"></span><span class="mord mathbb">R</span></span></span></span>. The recurrence is
given by</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mi>n</mi></msub></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\left(\begin{array}{cc} 1 & 1 \\ 1 & 0 \end{array} \right) \left( \begin{array}{c} F_{n-1} \\ F_{n-2} \end{array} \right) = \left(\begin{array}{c} F_{n-1} + F_{n-2} \\ F_{n-1} \end{array} \right) = \left(\begin{array}{c} F_n \\ F_{n-1} \end{array} \right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span></span></span>
</blockquote></div>
<p>and in general</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mi>n</mi></msup><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><msup><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mi>n</mi></msup><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mn>1</mn></msub></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mn>0</mn></msub></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mi>n</mi></msub></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\left( \begin{array}{cc} 1 & 1 \\ 1 & 0 \end{array} \right)^{n} \left( \begin{array}{c} 1 \\ 0 \end{array} \right) = \left( \begin{array}{cc} 1 & 1 \\ 1 & 0 \end{array} \right)^{n} \left( \begin{array}{c} F_1 \\ F_0 \end{array} \right) = \left(\begin{array}{c} F_{n + 1} \\ F_n \end{array} \right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.454322em;vertical-align:-0.95003em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.504292em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.454322em;vertical-align:-0.95003em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.504292em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span></span></span>
</blockquote></div>
<p>The matrix</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">A = \left(\begin{array}{cc} 1 & 1 \\ 1 & 0 \end{array} \right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span></span></span>
</blockquote></div>
<p>has characteristic polynomial</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>χ</mi><mi>A</mi></msub><mo stretchy="false">(</mo><mi>t</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><mi>t</mi><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mn>0</mn><mo>−</mo><mi>t</mi><mo stretchy="false">)</mo><mo>−</mo><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mn>1</mn><mo stretchy="false">)</mo><mo>=</mo><msup><mi>t</mi><mn>2</mn></msup><mo>−</mo><mi>t</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\chi_A(t) = (1 - t)(0 - t) - (1)(1) = t^2 - t - 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">χ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">t</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69841em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span></span>
</blockquote></div>
<p>If this polynomial has distinct roots, then <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi></mrow><annotation encoding="application/x-tex">A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span></span></span></span> is
diagonalizable (this is sufficient, but not necessary). Assuming the converse
we have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>χ</mi><mi>A</mi></msub><mo stretchy="false">(</mo><mi>t</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>t</mi><mo>−</mo><mi>α</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">\chi_A(t) = (t - \alpha)^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">χ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span> for some
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>∈</mo><msub><mi mathvariant="double-struck">F</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">\alpha \in \mathbb{F}_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.974998em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>; we can assume
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>∈</mo><msub><mi mathvariant="double-struck">F</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">\alpha \in \mathbb{F}_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.974998em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span>
since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>−</mo><mn>2</mn><mi>α</mi><mo>=</mo><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">-2\alpha = -1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord">1</span></span></span></span> is
the coefficient of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>t</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">t,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.80952em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">t</span><span class="mpunct">,</span></span></span></span> which means
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>=</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\alpha = 2^{-1} </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span> (we are fine with this since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi></mrow><annotation encoding="application/x-tex">p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span></span></span></span> odd means that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>2</mn><mrow><mo>−</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">2^{-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span> exists). In
order for this to be a root of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>χ</mi><mi>A</mi></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\chi_A,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">χ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> we must have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mn>0</mn><mo>≡</mo><mn>4</mn><mo>⋅</mo><msub><mi>χ</mi><mi>A</mi></msub><mrow><mo fence="true">(</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>1</mn></mrow></msup><mo fence="true">)</mo></mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≡</mo><mn>4</mn><mo>⋅</mo><mrow><mo fence="true">(</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>2</mn></mrow></msup><mo>−</mo><msup><mn>2</mn><mrow><mo>−</mo><mn>1</mn></mrow></msup><mo>−</mo><mn>1</mn><mo fence="true">)</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>≡</mo><mn>1</mn><mo>−</mo><mn>2</mn><mo>−</mo><mn>4</mn><mo>≡</mo><mo>−</mo><mn>5</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>p</mi><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} 0 \equiv 4 \cdot \chi_A\left(2^{-1}\right) &\equiv 4 \cdot \left(2^{-2} - 2^{-1} - 1\right) \\ &\equiv 1 - 2 - 4 \equiv -5 \bmod{p}. \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.024108em;vertical-align:-1.262054em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.762054em;"><span style="top:-3.897946em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">χ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span><span style="top:-2.397946em;"><span class="pstrut" style="height:3em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.262054em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.762054em;"><span style="top:-3.897946em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">2</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span><span style="top:-2.397946em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">−</span><span class="mord">5</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">p</span></span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.262054em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>p</mi><mo mathvariant="normal">≠</mo><mn>5</mn></mrow><annotation encoding="application/x-tex">p \neq 5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="inner"><span class="mord"><span class="mrel"></span></span></span><span class="fix"></span></span></span></span></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">5</span></span></span></span> is prime, this is not possible, hence
we reached a contradiction and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>χ</mi><mi>A</mi></msub></mrow><annotation encoding="application/x-tex">\chi_A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">χ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> does not have
a repeated root.</p>
<p>Thus we may write <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>χ</mi><mi>A</mi></msub><mo stretchy="false">(</mo><mi>t</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>t</mi><mo>−</mo><mi>α</mi><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mi>t</mi><mo>−</mo><mi>β</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\chi_A(t) = (t - \alpha)(t - \beta)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">χ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mclose">)</span></span></span></span> for
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo separator="true">,</mo><mi>β</mi><mo>∈</mo><msub><mi mathvariant="double-struck">F</mi><msup><mi>p</mi><mn>2</mn></msup></msub></mrow><annotation encoding="application/x-tex">\alpha, \beta \in \mathbb{F}_{p^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.002618em;vertical-align:-0.313728em;"></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.52238em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.313728em;"><span></span></span></span></span></span></span></span></span></span> (it's possible
that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>χ</mi><mi>A</mi></msub></mrow><annotation encoding="application/x-tex">\chi_A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">χ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is irreducible over
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi mathvariant="double-struck">F</mi><mi>p</mi></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\mathbb{F}_p,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.974998em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> but due to degree considerations it
<strong>must</strong> split completely over <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi mathvariant="double-struck">F</mi><msup><mi>p</mi><mn>2</mn></msup></msub></mrow><annotation encoding="application/x-tex">\mathbb{F}_{p^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.002618em;vertical-align:-0.313728em;"></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.52238em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.313728em;"><span></span></span></span></span></span></span></span></span></span>.
Using this, we may write</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>=</mo><mi>P</mi><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>α</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>β</mi></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><msup><mi>P</mi><mrow><mo>−</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">A = P \left(\begin{array}{cc} \alpha & 0 \\ 0 & \beta \end{array} \right) P^{-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05278em;">β</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>for some <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo>∈</mo><mi>G</mi><msub><mi>L</mi><mn>2</mn></msub><mrow><mo fence="true">(</mo><msub><mi mathvariant="double-struck">F</mi><msup><mi>p</mi><mn>2</mn></msup></msub><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">P \in GL_{2} \left(\mathbb{F}_{p^2}\right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72243em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.20001em;vertical-align:-0.35001em;"></span><span class="mord mathnormal">G</span><span class="mord"><span class="mord mathnormal">L</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.52238em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.313728em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span>
and so</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>A</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msup><mo>=</mo><mi>P</mi><msup><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>α</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>β</mi></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msup><msup><mi>P</mi><mrow><mo>−</mo><mn>1</mn></mrow></msup><mo>=</mo><mi>P</mi><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msup><mi>α</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msup></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><msup><mi>β</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msup></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><msup><mi>P</mi><mrow><mo>−</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">A^{p^2 - 1} = P \left(\begin{array}{cc} \alpha & 0 \\ 0 & \beta \end{array} \right)^{p^2 - 1} P^{-1} = P \left(\begin{array}{cc} \alpha^{p^2 - 1} & 0 \\ 0 & \beta^{p^2 - 1} \end{array} \right)P^{-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0369199999999998em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.0369199999999998em;"><span style="top:-3.1130000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.77685em;vertical-align:-0.95003em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05278em;">β</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.82682em;"><span style="top:-3.9029000000000007em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.0000299999999998em;vertical-align:-1.25003em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size4">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.59692em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9869199999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span><span style="top:-2.26308em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.09692em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.59692em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span><span style="top:-2.26308em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9869199999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.09692em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size4">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.864108em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>χ</mi><mi>A</mi></msub><mo stretchy="false">(</mo><mn>0</mn><mo stretchy="false">)</mo><mo>=</mo><mn>0</mn><mo>−</mo><mn>0</mn><mo>−</mo><mn>1</mn><mo mathvariant="normal">≠</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\chi_A(0) = 0 - 0 - 1 \neq 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">χ</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">A</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord">0</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="inner"><span class="mord"><span class="mrel"></span></span></span><span class="fix"></span></span></span></span></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> we know
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>β</mi></mrow><annotation encoding="application/x-tex">\beta</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span></span></span></span> are nonzero, hence
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>α</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msup><mo>=</mo><msup><mi>β</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msup><mo>=</mo><mn>1</mn><mo>∈</mo><msub><mi mathvariant="double-struck">F</mi><msup><mi>p</mi><mn>2</mn></msup></msub></mrow><annotation encoding="application/x-tex">\alpha^{p^2 - 1} = \beta^{p^2 - 1} = 1 \in \mathbb{F}_{p^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9869199999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9869199999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.18136em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9869199999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68354em;vertical-align:-0.0391em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.002618em;vertical-align:-0.313728em;"></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.52238em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.313728em;"><span></span></span></span></span></span></span></span></span></span>.
Thus <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>A</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msup><mo>=</mo><mi>P</mi><msub><mi>I</mi><mn>2</mn></msub><msup><mi>P</mi><mrow><mo>−</mo><mn>1</mn></mrow></msup><mo>=</mo><msub><mi>I</mi><mn>2</mn></msub></mrow><annotation encoding="application/x-tex">A^{p^2 - 1} = P I_2 P^{-1} = I_2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9869199999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.9869199999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.964108em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and so</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mi>p</mi></msub></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>F</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msub></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><msup><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msup><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><msub><mi>I</mi><mn>2</mn></msub><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.1600em" columnalign="center" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">\left(\begin{array}{c} F_p \\ F_{p^2 - 1} \end{array} \right) = \left(\begin{array}{cc} 1 & 1 \\ 1 & 0 \end{array} \right)^{p^2 - 1} \left(\begin{array}{c} 1 \\ 0 \end{array} \right) = I_2 \left( \begin{array}{c} 1 \\ 0 \end{array} \right) = \left( \begin{array}{c} 1 \\ 0 \end{array} \right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.52238em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.313728em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.77685em;vertical-align:-0.95003em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.82682em;"><span style="top:-3.9029000000000007em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913142857142857em;"><span style="top:-2.931em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.07847em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span></span></span>
</blockquote></div>
<p>so we have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mrow><msup><mi>p</mi><mn>2</mn></msup><mo>−</mo><mn>1</mn></mrow></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">F_{p^2 - 1} = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.997058em;vertical-align:-0.313728em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3448em;"><span style="top:-2.52238em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">p</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.313728em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> in
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi mathvariant="double-struck">F</mi><mi>p</mi></msub></mrow><annotation encoding="application/x-tex">\mathbb{F}_p</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.974998em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathbb">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.15139200000000003em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span> as desired.</p>Bridging OAuth 2.0 objects between GData and Discovery2012-12-24T00:00:00-08:002012-12-24T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-12-24:/2012/12/bridging-oauth-20-objects-between-gdata.html<p>My colleague
<a href="http://plus.google.com/110554344789668969711">+Takashi Matsuo</a> and I recently
gave a <a href="http://www.youtube.com/watch?v=HoUdWBzUZ-M">talk</a> about using
<code>OAuth2Decorator</code> (from the <code>google-api-python-client</code>
<a href="http://code.google.com/p/google-api-python-client/">library</a>) with
request handlers in
<a href="https://developers.google.com/appengine/">Google App Engine</a>. Shortly after, a
<a href="http://stackoverflow.com/questions/13981641">Stack Overflow question</a>
sprung up asking about the right way to use the decorator and, as a
follow up, if the decorator could …</p><p>My colleague
<a href="http://plus.google.com/110554344789668969711">+Takashi Matsuo</a> and I recently
gave a <a href="http://www.youtube.com/watch?v=HoUdWBzUZ-M">talk</a> about using
<code>OAuth2Decorator</code> (from the <code>google-api-python-client</code>
<a href="http://code.google.com/p/google-api-python-client/">library</a>) with
request handlers in
<a href="https://developers.google.com/appengine/">Google App Engine</a>. Shortly after, a
<a href="http://stackoverflow.com/questions/13981641">Stack Overflow question</a>
sprung up asking about the right way to use the decorator and, as a
follow up, if the decorator could be used with the
<a href="https://developers.google.com/google-apps/provisioning/">Google Apps Provisioning API</a>.
As I mentioned in my answer,</p>
<blockquote>
<p>The Google Apps Provisioning API is a
<a href="https://developers.google.com/gdata/docs/2.0/reference">Google Data API</a> ...
As a result, you'll need to use the <code>gdata-python-client</code>
<a href="http://code.google.com/p/gdata-python-client/">library</a> to use the
Provisioning API. Unfortunately, you'll need to manually convert from a
<a href="http://code.google.com/p/google-api-python-client/source/browse/oauth2client/client.py?r=efd0ccd31d6c16ddf9f65ba5c31c7033749be0e1#349"><code>oauth2client.client.OAuth2Credentials</code> object</a>
to a
<a href="http://code.google.com/p/gdata-python-client/source/browse/src/gdata/gauth.py?r=cf0208e89433800c713495654774f36d84e894b3#1143"><code>gdata.gauth.OAuth2Token</code> object</a>
to use the same token for either one.</p>
</blockquote>
<p>Instead of making everyone and their brother write their own, I thought
I'd take a stab at it and write about it here. The general philosophy I
took was that the token subclass should be 100% based on an
<code>OAuth2Credentials</code> object:</p>
<ul>
<li>the token constructor simply takes an <code>OAuth2Credentials</code> object</li>
<li>the token refresh updates the <code>OAuth2Credentials</code> object set on the token</li>
<li>values of the current tokencan be updated directly from the
<code>OAuth2Credentials</code> object set on the token</li>
</ul>
<p>Starting from the top, we'll use two imports:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">httplib2</span>
<span class="kn">from</span> <span class="nn">gdata.gauth</span> <span class="kn">import</span> <span class="n">OAuth2Token</span>
</code></pre></div>
<p>The first is needed to refresh an <code>OAuth2Credentials</code> object
using the mechanics native to <code>google-api-python-client</code>,
and the second is needed so we may subclass the <code>gdata-python-client</code> native
token class.</p>
<p>As I mentioned, the values should be updated directly from an
<code>OAuth2Credentials</code> object, so in our constructor, we first initialize the
values to <code>None</code> and then call our update method to actually set the values.
This allows us to write less code, because,
<a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">repeating is bad</a>
(I think someone told me that once?).</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">OAuth2TokenFromCredentials</span><span class="p">(</span><span class="n">OAuth2Token</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">credentials</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">credentials</span> <span class="o">=</span> <span class="n">credentials</span>
<span class="nb">super</span><span class="p">(</span><span class="n">OAuth2TokenFromCredentials</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">UpdateFromCredentials</span><span class="p">()</span>
</code></pre></div>
<p>We can get away with passing four <code>None</code>s to the superclass constructor, as it
only has four positional arguments: <code>client_id</code>, <code>client_secret</code>, <code>scope</code>,
and <code>user_agent</code>.</p>
<p>Three of those have equivalents on the <code>OAuth2Credentials</code> object, but there
is no place for <code>scope</code> because that part of the token exchange is handled
<a href="https://code.google.com/p/google-api-python-client/source/browse/oauth2client/client.py?r=efd0ccd31d6c16ddf9f65ba5c31c7033749be0e1#1030">elsewhere</a>
in the <code>google-api-python-client</code> library.</p>
<div class="highlight"><pre><span></span><code> <span class="k">def</span> <span class="nf">UpdateFromCredentials</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">client_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">client_id</span>
<span class="bp">self</span><span class="o">.</span><span class="n">client_secret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">client_secret</span>
<span class="bp">self</span><span class="o">.</span><span class="n">user_agent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">user_agent</span>
<span class="o">...</span>
</code></pre></div>
<p>Similarly, the <code>OAuth2Credentials</code> object only implements the refresh part of
the OAuth 2.0 flow, so only has the token URI, hence <code>auth_uri</code>, <code>revoke_uri</code>,
<code>redirect</code>, and <code>_uri</code> will not be set either. However, the token URI and the
token data are the same for both.</p>
<div class="highlight"><pre><span></span><code> <span class="o">...</span>
<span class="bp">self</span><span class="o">.</span><span class="n">token_uri</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">token_uri</span>
<span class="bp">self</span><span class="o">.</span><span class="n">access_token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">access_token</span>
<span class="bp">self</span><span class="o">.</span><span class="n">refresh_token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">refresh_token</span>
<span class="o">...</span>
</code></pre></div>
<p>Finally, we copy the extra fields which may be set outside of a
constructor:</p>
<div class="highlight"><pre><span></span><code> <span class="o">...</span>
<span class="bp">self</span><span class="o">.</span><span class="n">token_expiry</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">token_expiry</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_invalid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">invalid</span>
</code></pre></div>
<p>Since <code>OAuth2Credentials</code> doesn't deal with all parts of the OAuth 2.0
process, we disable those methods from <code>OAuth2Token</code> that do.</p>
<div class="highlight"><pre><span></span><code> <span class="k">def</span> <span class="nf">generate_authorize_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span>
<span class="k">def</span> <span class="nf">get_access_token</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span>
<span class="k">def</span> <span class="nf">revoke</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span>
<span class="k">def</span> <span class="nf">_extract_tokens</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="k">raise</span> <span class="ne">NotImplementedError</span>
</code></pre></div>
<p>Finally, the last method which needs to be implemented is <code>_refresh</code>,
which should refresh the <code>OAuth2Credentials</code> object and then update the
current GData token after the refresh. Instead of using the passed in request
object, we use one from <code>httplib2</code> as we mentioned in imports.</p>
<div class="highlight"><pre><span></span><code> <span class="k">def</span> <span class="nf">_refresh</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">unused_request</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">credentials</span><span class="o">.</span><span class="n">_refresh</span><span class="p">(</span><span class="n">httplib2</span><span class="o">.</span><span class="n">Http</span><span class="p">()</span><span class="o">.</span><span class="n">request</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">UpdateFromCredentials</span><span class="p">()</span>
</code></pre></div>
<p>After refreshing the <code>OAuth2Credentials</code> object, we can update the current
token using the same method called in the constructor.</p>
<p>Using this class, we can simultaneously call a
<a href="https://developers.google.com/discovery/v1/getting_started#background">discovery-based API</a>
and a GData API:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">apiclient.discovery</span> <span class="kn">import</span> <span class="n">build</span>
<span class="kn">from</span> <span class="nn">gdata.contacts.client</span> <span class="kn">import</span> <span class="n">ContactsClient</span>
<span class="n">service</span> <span class="o">=</span> <span class="n">build</span><span class="p">(</span><span class="s1">'calendar'</span><span class="p">,</span> <span class="s1">'v3'</span><span class="p">,</span> <span class="n">developerKey</span><span class="o">=</span><span class="s1">'...'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">MainHandler</span><span class="p">(</span><span class="n">webapp2</span><span class="o">.</span><span class="n">RequestHandler</span><span class="p">):</span>
<span class="nd">@decorator</span><span class="o">.</span><span class="n">oauth_required</span>
<span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">auth_token</span> <span class="o">=</span> <span class="n">OAuth2TokenFromCredentials</span><span class="p">(</span><span class="n">decorator</span><span class="o">.</span><span class="n">credentials</span><span class="p">)</span>
<span class="n">contacts_client</span> <span class="o">=</span> <span class="n">ContactsClient</span><span class="p">()</span>
<span class="n">auth_token</span><span class="o">.</span><span class="n">authorize</span><span class="p">(</span><span class="n">contacts_client</span><span class="p">)</span>
<span class="n">contacts</span> <span class="o">=</span> <span class="n">contacts_client</span><span class="o">.</span><span class="n">get_contacts</span><span class="p">()</span>
<span class="o">...</span>
<span class="n">events</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="n">events</span><span class="p">()</span><span class="o">.</span><span class="n">list</span><span class="p">(</span><span class="n">calendarId</span><span class="o">=</span><span class="s1">'primary'</span><span class="p">)</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
<span class="n">http</span><span class="o">=</span><span class="n">decorator</span><span class="o">.</span><span class="n">http</span><span class="p">())</span>
<span class="o">...</span>
</code></pre></div>Last to Cross the Finish Line: Part Three2012-09-10T00:00:00-07:002012-09-10T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-09-10:/2012/09/last-to-cross-finish-line-part-three.html<p>Recently, my colleague
<a href="https://plus.google.com/115640166224745944209">+Fred Sauer</a> and I gave a tech
talk called "Last Across the Finish Line: Asynchronous
<a href="https://developers.google.com/appengine/docs/python/taskqueue/overview">Tasks</a>
with <a href="https://appengine.google.com/">App Engine</a>". This is part three in
a three part series where I will share our
<a href="http://www.forbes.com/pictures/ekij45gdh/learnings/#gallerycontent">learnings</a>
and give some helpful references to the
<a href="https://developers.google.com/appengine/docs/">App Engine documentation</a>.</p>
<p>Check out the …</p><p>Recently, my colleague
<a href="https://plus.google.com/115640166224745944209">+Fred Sauer</a> and I gave a tech
talk called "Last Across the Finish Line: Asynchronous
<a href="https://developers.google.com/appengine/docs/python/taskqueue/overview">Tasks</a>
with <a href="https://appengine.google.com/">App Engine</a>". This is part three in
a three part series where I will share our
<a href="http://www.forbes.com/pictures/ekij45gdh/learnings/#gallerycontent">learnings</a>
and give some helpful references to the
<a href="https://developers.google.com/appengine/docs/">App Engine documentation</a>.</p>
<p>Check out the
<a href="/2012/08/last-to-cross-finish-line-part-two.html">previous post</a> if
you haven't already.In this section, we'll define the <code>PopulateBatch</code> function
and explore the
<a href="https://developers.google.com/appengine/docs/python/ndb/"><code>ndb</code> models</a>
and
<a href="https://developers.google.com/appengine/docs/python/taskqueue/">Task Queue</a>
operations that make it work.</p>
<h2>Imports</h2>
<p>Before defining the
<a href="https://developers.google.com/appengine/docs/python/ndb/">models</a> and
helper functions in
<a href="http://code.google.com/p/gae-last-across-the-finish-line/source/browse/models.py"><code>models.py</code></a>,
let's first review the imports:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">google.appengine.api</span> <span class="kn">import</span> <span class="n">channel</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.deferred</span> <span class="kn">import</span> <span class="n">defer</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext</span> <span class="kn">import</span> <span class="n">ndb</span>
</code></pre></div>
<p>Again, we import <a href="http://docs.python.org/library/json.html"><code>json</code></a>
and <code>channel</code> for serialization and message passing. We import the
<code>defer</code> function from the
<a href="https://developers.google.com/appengine/articles/deferred">deferred library</a> to
abstract away task creation and take advantage of the ability to "defer"
a function call to another thread of execution. Finally, we import <code>ndb</code>
as a means for interacting with the App Engine
<a href="https://developers.google.com/appengine/docs/python/datastore/overview">Datastore</a>.</p>
<h2>Method Wrapper Built for Tasks</h2>
<p>As we saw in the <code>BeginWork</code> handler
in <a href="/2012/08/last-to-cross-finish-line-part-two.html">part two</a>,
units of work are passed to <code>PopulateBatch</code>
as 3-tuples containing a method, the positional arguments and the
keyword arguments to that method.</p>
<p>In order to keep our task from hanging indefinitely due to unseen errors
and to implicitly include the work unit in the batch, we define a
wrapper around these method calls:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">AlwaysComplete</span><span class="p">(</span><span class="n">task</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">method</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span> <span class="c1"># TODO: Consider failing differently.</span>
<span class="k">pass</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">defer</span><span class="p">(</span><span class="n">task</span><span class="o">.</span><span class="n">Complete</span><span class="p">)</span>
</code></pre></div>
<p>As you can see, we catch any and all errors thrown by our method and
don't retry the method if it fails. In our example, if the call
<code>method(*args, **kwargs)</code> fails, the data won't be sent through the channel and
the given square will not show up in the quilt. However, since we catch
these exceptions, the batch will complete and the spinner will disappear
with this square still missing.</p>
<p>This part is likely going to be customized to the specific work
involved, but for our case, we didn't want individual failures to cause
the whole batch to fail. In addition, we implicitly link the work unit
with a special type of task object in the datastore.</p>
<p>In the <code>finally</code> section of the error catch, we defer the <code>Complete</code>
method on the task corresponding to this work unit. We defer the call to
this complete method in order to avoid any errors (possibly from a
failed datastore action) that the method may cause. If it were to throw
an error, since <code>AlwaysComplete</code> is called in a deferred task, the task
would retry and our worker unit would execute (or fail) again, which is bad
if our user interface is not
<a href="http://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning">idempotent</a>.</p>
<h2>Task Model</h2>
<p>As we saw above, we need a datastore model to represent tasks within a
batch. We start out initially with a model having only one attribute — a
boolean representing whether or not the task has completed.</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">BatchTask</span><span class="p">(</span><span class="n">ndb</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
<span class="c1"># Very important that the default value True of `indexed` is used here</span>
<span class="c1"># since we need to query on BatchTask.completed</span>
<span class="n">completed</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">BooleanProperty</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</code></pre></div>
<p>As we know, we'll need to define a <code>Complete</code> method in order to use the task
in <code>AlwaysComplete</code>, but before doing so, we'll define another method which
will put the task object in the datastore and pass a unit of work to
<code>AlwaysComplete</code>:</p>
<div class="highlight"><pre><span></span><code> <span class="nd">@ndb</span><span class="o">.</span><span class="n">transactional</span>
<span class="k">def</span> <span class="nf">Populate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">put</span><span class="p">()</span>
<span class="n">kwargs</span><span class="p">[</span><span class="s1">'_transactional'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">defer</span><span class="p">(</span><span class="n">AlwaysComplete</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</code></pre></div>
<p>In this <code>Populate</code> method, we first put the object in the datastore
<a href="https://developers.google.com/appengine/docs/python/datastore/transactions">transactionally</a>
by using the <code>ndb.transactional</code> decorator. By adding the <code>_transactional</code>
keyword to the keyword arguments, <code>defer</code>
<a href="http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/deferred/deferred.py?r=277#250">strips away</a>
the underscore and creates a
<a href="https://developers.google.com/appengine/docs/python/taskqueue/overview#Tasks_within_Transactions">transactional task</a>.
By doing this</p>
<blockquote>
<p>the task is only enqueued — and guaranteed to be enqueued — if the
transaction is committed successfully.</p>
</blockquote>
<p>We need this deferred task to be enqueued transactionally for consistency of
the <code>completed</code> boolean attribute. The datastore put in <code>Populate</code> uses the
default value of <code>False</code>, but after <code>Complete</code> is called we want to set this
boolean to <code>True</code>. If this value was not
<a href="https://developers.google.com/appengine/docs/python/datastore/transactions#Isolation_and_Consistency">consistent</a>,
we may have a race condition that resulted in a completed task in the
datastore being marked as incomplete. As we'll see later, we rely on
this consistency for a query that will help us determine if our batch is
done.</p>
<p>To signal that a unit of work has completed, we define the <code>Complete</code>
method on the task object:</p>
<div class="highlight"><pre><span></span><code> <span class="nd">@ndb</span><span class="o">.</span><span class="n">transactional</span>
<span class="k">def</span> <span class="nf">Complete</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">completed</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">put</span><span class="p">()</span>
<span class="n">batcher_parent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">parent</span><span class="p">()</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
<span class="n">defer</span><span class="p">(</span><span class="n">batcher_parent</span><span class="o">.</span><span class="n">CheckComplete</span><span class="p">,</span> <span class="n">_transactional</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</code></pre></div>
<p>It performs two functions. First, it sets <code>completed</code> to <code>True</code>
in a transaction. Second, it retrieves the parent
<a href="https://developers.google.com/appengine/docs/python/ndb/entities">entity</a>
of the task object and defers the <code>CheckComplete</code> method on this parent.
As we will see in more depth in the <code>PopulateBatch</code> function, we use a special
type of batch parent object to create an
<a href="https://developers.google.com/appengine/docs/python/datastore/entities#Transactions_and_Entity_Groups">entity group</a>
containing all the worker tasks for the batch. We don't want to check if
the batch has completed until the datastore put has succeeded, so we
defer the call to call to <code>CheckComplete</code> transactionally, just as we did
with <code>AlwaysComplete</code> in the <code>Populate</code> method.</p>
<blockquote>
<p><strong>NOTE</strong>: It may seem that these <code>get</code> calls to retrieve the parent via
<code>self.key.parent().get()</code> are using more bandwidth than necessary. However,
we are relying here on the power of <code>ndb</code>. Using a combination of instance
caching and
<a href="https://developers.google.com/appengine/docs/python/memcache/overview">memcache</a>,
most (if not all) of these gets will use the cache and will not incur
the cost of a round-trip to the datastore.</p>
</blockquote>
<h2>Batch Parent Model</h2>
<p>Given what we rely on in <code>BatchTask</code>, we need to define a special type of
datastore object that will act as the parent entity for a batch. Since we are
going to use it to check when a batch is complete, we define the boolean
attribute <code>all_tasks_loaded</code> to signal whether or not all worker tasks from
the batch have begun. We can use this as a short circuit in our <code>CheckComplete</code>
method (or as a guard against premature completion).</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">TaskBatcher</span><span class="p">(</span><span class="n">ndb</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
<span class="n">all_tasks_loaded</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">BooleanProperty</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">indexed</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</code></pre></div>
<p>To check if a batch is complete, we first determine if all tasks have
loaded. If that is the case, we perform an
<a href="https://developers.google.com/appengine/docs/python/datastore/queries#Ancestor_Queries">ancestor query</a>
that simply attempts to fetch the first worker task in the entity group
which has not yet completed. If such a task does not exist, we know the
batch has completed, and so start to clean up the task and batch parent
objects from the datastore.</p>
<div class="highlight"><pre><span></span><code> <span class="k">def</span> <span class="nf">CheckComplete</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># Does not need to be transactional since it doesn't change data</span>
<span class="n">session_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">id</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">all_tasks_loaded</span><span class="p">:</span>
<span class="n">incomplete</span> <span class="o">=</span> <span class="n">BatchTask</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BatchTask</span><span class="o">.</span><span class="n">completed</span> <span class="o">==</span> <span class="kc">False</span><span class="p">,</span>
<span class="n">ancestor</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">)</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">incomplete</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">channel</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">session_id</span><span class="p">,</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s1">'status'</span><span class="p">:</span> <span class="s1">'complete'</span><span class="p">}))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">CleanUp</span><span class="p">()</span>
<span class="k">return</span>
<span class="n">channel</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">session_id</span><span class="p">,</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s1">'status'</span><span class="p">:</span> <span class="s1">'incomplete'</span><span class="p">}))</span>
</code></pre></div>
<p>We again do the utmost at this step to ensure consistency
by using an ancestor query:</p>
<blockquote>
<p>There are scenarios in which any pending modifications are guaranteed
to be completely applied ... any ancestor queries in the High
Replication datastore. In both cases, query results will always be
current and consistent.</p>
</blockquote>
<p>After checking if a batch is complete, we need to communicate the status
back to the client. We'll rely on <code>PopulateBatch</code> to create instances of
<code>TaskBatcher</code> with the ID of the session corresponding to the batch as the
datastore key. We send a status complete or incomplete message to the client
using the session ID for the channel. In order to correctly handle these
messages on the client, we'll need to update the <code>onmessage</code> handler (defined
in <a href="/2012/08/last-to-cross-finish-line-part-two.html">part two</a>)
to account for status updates:</p>
<div class="highlight"><pre><span></span><code><span class="nx">socket</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">msg</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span> <span class="o">!==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">setStatus</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">squareIndex</span> <span class="o">=</span> <span class="mf">8</span><span class="o">*</span><span class="nx">response</span><span class="p">.</span><span class="nx">row</span> <span class="o">+</span> <span class="nx">response</span><span class="p">.</span><span class="nx">column</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">squareId</span> <span class="o">=</span> <span class="s1">'#square'</span> <span class="o">+</span> <span class="nx">squareIndex</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">squareId</span><span class="p">).</span><span class="nx">css</span><span class="p">(</span><span class="s1">'background-color'</span><span class="p">,</span> <span class="nx">response</span><span class="p">.</span><span class="nx">color</span><span class="p">);</span>
<span class="p">}}</span>
</code></pre></div>
<p>Just as the <code>setStatus</code> method revealed the progress spinner when work began,
it will remove the spinner when the status is complete.</p>
<p>We'll next define the <code>CleanUp</code> method that is called when the batch is
complete:</p>
<div class="highlight"><pre><span></span><code> <span class="k">def</span> <span class="nf">CleanUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">children</span> <span class="o">=</span> <span class="n">BatchTask</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">ancestor</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">)</span><span class="o">.</span><span class="n">iter</span><span class="p">(</span><span class="n">keys_only</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">ndb</span><span class="o">.</span><span class="n">delete_multi</span><span class="p">(</span><span class="n">children</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="o">.</span><span class="n">delete</span><span class="p">()</span>
</code></pre></div>
<p>This method uses the key from the batch parent to perform another ancestor
query and creates an object which can
<a href="https://developers.google.com/appengine/docs/python/ndb/queries#iterators">iterate over all the keys</a>
of the tasks in the batch. By using the <code>delete_multi</code> function provided
by <code>ndb</code>, we are able to delete these in parallel rather than waiting for each
to complete. After deleting all the tasks, the batcher deletes itself and
clean up is done. Since the <code>TaskBatcher.CheckComplete</code> spawns <code>CleanUp</code> in
a deferred task, if the deletes time out, the task will try again until
all tasks in the batch are deleted.</p>
<p>As a final method on <code>TaskBatcher</code>, we define something similar to
<code>BatchTask.Populate</code> that is triggered after all workers in the batch have been
added:</p>
<div class="highlight"><pre><span></span><code> <span class="nd">@ndb</span><span class="o">.</span><span class="n">transactional</span>
<span class="k">def</span> <span class="nf">Ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">all_tasks_loaded</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">put</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">CheckComplete</span><span class="p">()</span>
</code></pre></div>
<p>This simply signals that all tasks from the batch have loaded by setting
<code>all_tasks_loaded</code> to <code>True</code> and calls <code>CheckComplete</code> in case all the tasks
in the batch have already completed. This check is necessary because if all
worker tasks complete before <code>all_tasks_loaded</code> is <code>True</code>, then none of the
checks initiated by those tasks would signal completion. We use a transaction
to avoid a race condition with the initial datastore put — a put which is
a signal that all tasks have <strong>not</strong> loaded.</p>
<h2>Populating a Batch</h2>
<p>With our two models in hand, we are finally ready to define the <code>PopulateBatch</code>
function used (in
<a href="/2012/08/last-to-cross-finish-line-part-two.html">part two</a>)
by the <code>BeginWork</code> handler. We want users of this function to be able to call
it directly, but don't want it to block the process they call it in, so we wrap
the real function in a function that will simply defer the work:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">PopulateBatch</span><span class="p">(</span><span class="n">session_id</span><span class="p">,</span> <span class="n">work</span><span class="p">):</span>
<span class="n">defer</span><span class="p">(</span><span class="n">_PopulateBatch</span><span class="p">,</span> <span class="n">session_id</span><span class="p">,</span> <span class="n">work</span><span class="p">)</span>
</code></pre></div>
<p>In the actual function, we first create a <code>TaskBatcher</code> object using the
session ID as the key and put it into the datastore using the default value of
<code>False</code> for <code>all_tasks_loaded</code>. Since this is a single synchronous <code>put</code>, it
blocks the thread of execution and we can be sure our parent is in the datastore
before members of the entity group (the task objects) are created.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">_PopulateBatch</span><span class="p">(</span><span class="n">session_id</span><span class="p">,</span> <span class="n">work</span><span class="p">):</span>
<span class="n">batcher_key</span> <span class="o">=</span> <span class="n">ndb</span><span class="o">.</span><span class="n">Key</span><span class="p">(</span><span class="n">TaskBatcher</span><span class="p">,</span> <span class="n">session_id</span><span class="p">)</span>
<span class="n">batcher</span> <span class="o">=</span> <span class="n">TaskBatcher</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">batcher_key</span><span class="p">)</span>
<span class="n">batcher</span><span class="o">.</span><span class="n">put</span><span class="p">()</span>
</code></pre></div>
<p>After doing this, we loop through all the 3-tuples in the passed in batch of
<code>work</code>. For each unit of work, we create a task using the batcher as parent and
then call the <code>Populate</code> method on the task using the method, positional
arguments and keyword arguments provided in the unit of work.</p>
<div class="highlight"><pre><span></span><code> <span class="k">for</span> <span class="n">method</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="ow">in</span> <span class="n">work</span><span class="p">:</span>
<span class="n">task</span> <span class="o">=</span> <span class="n">BatchTask</span><span class="p">(</span><span class="n">parent</span><span class="o">=</span><span class="n">batcher_key</span><span class="p">)</span>
<span class="n">task</span><span class="o">.</span><span class="n">Populate</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</code></pre></div>
<p>Finally, to signal that all tasks in the batch have been added, we call
the <code>Ready</code> method on the batch parent:</p>
<div class="highlight"><pre><span></span><code> <span class="n">batcher</span><span class="o">.</span><span class="n">Ready</span><span class="p">()</span>
</code></pre></div>
<blockquote>
<p><strong>Note:</strong> This approach can cause performance issues as the number of
tasks grows, since contentious puts within the entity group can cause
task completions to stall or retry. I (or my colleagues) will be
following up with two posts on the following topics:</p>
<ul>
<li>using task tagging and pull queues to achieve a similar result, but
reducing contention</li>
<li>exploring ways to extend this model to a hierarchical model where
tasks may have subtasks</li>
</ul>
</blockquote>Last to Cross the Finish Line: Part Two2012-08-29T00:00:00-07:002012-08-29T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-08-29:/2012/08/last-to-cross-finish-line-part-two.html<p>Recently, my colleague
<a href="https://plus.google.com/115640166224745944209">+Fred Sauer</a> and I gave a tech
talk called "Last Across the Finish Line: Asynchronous
<a href="https://developers.google.com/appengine/docs/python/taskqueue/overview">Tasks</a>
with <a href="https://appengine.google.com/">App Engine</a>".
This is part two in a three part series where I will share our
<a href="http://www.forbes.com/pictures/ekij45gdh/learnings/#gallerycontent">learnings</a>
and give some helpful references to the
<a href="https://developers.google.com/appengine/docs/">App Engine documentation</a>.</p>
<p>Check out the …</p><p>Recently, my colleague
<a href="https://plus.google.com/115640166224745944209">+Fred Sauer</a> and I gave a tech
talk called "Last Across the Finish Line: Asynchronous
<a href="https://developers.google.com/appengine/docs/python/taskqueue/overview">Tasks</a>
with <a href="https://appengine.google.com/">App Engine</a>".
This is part two in a three part series where I will share our
<a href="http://www.forbes.com/pictures/ekij45gdh/learnings/#gallerycontent">learnings</a>
and give some helpful references to the
<a href="https://developers.google.com/appengine/docs/">App Engine documentation</a>.</p>
<p>Check out the
<a href="/2012/08/last-to-cross-finish-line-part-one.html">previous post</a>
if you haven't already. In this section, we'll cover the two
<a href="https://developers.google.com/appengine/docs/python/tools/webapp/running">WSGI handlers</a>
in
<a href="http://code.google.com/p/gae-last-across-the-finish-line/source/browse/main.py"><code>main.py</code></a>
serving requests for our application and the client side code that
communicates with our application.</p>
<h2>Imports</h2>
<p>Before defining the handlers, let's first review the imports:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">google.appengine.api</span> <span class="kn">import</span> <span class="n">channel</span>
<span class="kn">from</span> <span class="nn">google.appengine.api</span> <span class="kn">import</span> <span class="n">users</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.webapp.util</span> <span class="kn">import</span> <span class="n">login_required</span>
<span class="kn">import</span> <span class="nn">webapp2</span>
<span class="kn">from</span> <span class="nn">webapp2_extras</span> <span class="kn">import</span> <span class="n">jinja2</span>
<span class="kn">from</span> <span class="nn">display</span> <span class="kn">import</span> <span class="n">RandomRowColumnOrdering</span>
<span class="kn">from</span> <span class="nn">display</span> <span class="kn">import</span> <span class="n">SendColor</span>
<span class="kn">from</span> <span class="nn">models</span> <span class="kn">import</span> <span class="n">PopulateBatch</span>
</code></pre></div>
<p>We import <a href="http://docs.python.org/library/json.html"><code>json</code></a>
for serialization of messages. Specific to App Engine, we import <code>channel</code>
to use the
<a href="https://developers.google.com/appengine/docs/python/channel/">Channel API</a>,
<a href="https://developers.google.com/appengine/docs/python/users/"><code>users</code></a>
and
<a href="https://developers.google.com/appengine/docs/python/tools/webapp/utilmodule"><code>login_required</code></a>
for authenticating users within a request,
<a href="https://developers.google.com/appengine/docs/python/gettingstartedpython27/usingwebapp"><code>webapp2</code></a>
for creating
<a href="http://webapp-improved.appspot.com/guide/app.html">WSGI Handlers</a>
and
<a href="https://developers.google.com/appengine/docs/python/gettingstartedpython27/templates"><code>jinja2</code></a>
for templating.</p>
<p>Finally, we import four functions from the two other modules defined within our
project. From the
<a href="http://code.google.com/p/gae-last-across-the-finish-line/source/browse/display.py"><code>display</code></a>
module, we import the <code>SendColor</code>function that we explored in part oneand the
<code>RandomRowColumnOrdering</code> function, which generates all possible row, column
pairs in a random order. From the as of yet undiscussed
<a href="http://code.google.com/p/gae-last-across-the-finish-line/source/browse/models.py"><code>models</code></a>
module we import the <code>PopulateBatch</code> function, which takes a session ID and a
batch of work to be done and spawns workers to carry out the batch of work.</p>
<h2>Handlers</h2>
<p>This module defines two handlers: the main page for the user interface
and an <a href="http://en.wikipedia.org/wiki/Ajax_(programming)">AJAX</a> handler
which will begin spawning the workers.</p>
<p>For the main page we use <code>jinja2</code> templates to render from the template
<a href="http://code.google.com/p/gae-last-across-the-finish-line/source/browse/templates/main.html"><code>main.html</code></a>
in the <code>templates</code> folder:</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">MainPage</span><span class="p">(</span><span class="n">webapp2</span><span class="o">.</span><span class="n">RequestHandler</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">RenderResponse</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">template</span><span class="p">,</span> <span class="o">**</span><span class="n">context</span><span class="p">):</span>
<span class="n">jinja2_renderer</span> <span class="o">=</span> <span class="n">jinja2</span><span class="o">.</span><span class="n">get_jinja2</span><span class="p">(</span><span class="n">app</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="p">)</span>
<span class="n">rendered_value</span> <span class="o">=</span> <span class="n">jinja2_renderer</span><span class="o">.</span><span class="n">render_template</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="o">**</span><span class="n">context</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">response</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">rendered_value</span><span class="p">)</span>
<span class="nd">@login_required</span>
<span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">user_id</span> <span class="o">=</span> <span class="n">users</span><span class="o">.</span><span class="n">get_current_user</span><span class="p">()</span><span class="o">.</span><span class="n">user_id</span><span class="p">()</span>
<span class="n">token</span> <span class="o">=</span> <span class="n">channel</span><span class="o">.</span><span class="n">create_channel</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">RenderResponse</span><span class="p">(</span><span class="s1">'main.html'</span><span class="p">,</span> <span class="n">token</span><span class="o">=</span><span class="n">token</span><span class="p">,</span> <span class="n">table_id</span><span class="o">=</span><span class="s1">'pixels'</span><span class="p">,</span>
<span class="n">rows</span><span class="o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n">columns</span><span class="o">=</span><span class="mi">8</span><span class="p">)</span>
</code></pre></div>
<p>In <code>get</code> — the actual handler serving the
<a href="http://en.wikipedia.org/wiki/GET_(HTTP)#Request_methods">GET</a> request
from the browser — we use the <code>login_required</code> decorator to make
sure the user is signed in, and then create a channel for message passing
using the ID of the signed in user. The template takes an HTML ID, rows and
columns to create an HTML table as the "quilt" that the user will see. We pass
the created token for the channel, an HTML ID for the table and the rows and
columns to the template by simply specifying them as keyword arguments.</p>
<p>For the handler which will spawn the workers, we use <code>RandomRowColumnOrdering</code>
to generate row, column pairs. Using each pair along with the <code>SendColor</code>
function and the user ID (as a proxy for session ID) for message passing, we
add a unit of work to the batch</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">BeginWork</span><span class="p">(</span><span class="n">webapp2</span><span class="o">.</span><span class="n">RequestHandler</span><span class="p">):</span>
<span class="c1"># Can't use login_required decorator here because it is not</span>
<span class="c1"># supported for POST requests</span>
<span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">response</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'batch_populated'</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># Will raise an AttributeError if no current user</span>
<span class="n">user_id</span> <span class="o">=</span> <span class="n">users</span><span class="o">.</span><span class="n">get_current_user</span><span class="p">()</span><span class="o">.</span><span class="n">user_id</span><span class="p">()</span>
<span class="c1"># TODO: return 400 if not logged in</span>
<span class="n">work</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">row</span><span class="p">,</span> <span class="n">column</span> <span class="ow">in</span> <span class="n">RandomRowColumnOrdering</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">):</span>
<span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">row</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">user_id</span><span class="p">)</span>
<span class="n">work</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">SendColor</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="p">{}))</span> <span class="c1"># No keyword args</span>
<span class="n">PopulateBatch</span><span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">work</span><span class="p">)</span>
<span class="n">response</span><span class="p">[</span><span class="s1">'batch_populated'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">except</span><span class="p">:</span>
<span class="c1"># TODO: Consider logging traceback.format_exception(*sys.exc_info()) here</span>
<span class="k">pass</span>
<span class="bp">self</span><span class="o">.</span><span class="n">response</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">response</span><span class="p">))</span>
</code></pre></div>
<p>Finally, for routing applications within our app, we define:</p>
<div class="highlight"><pre><span></span><code><span class="n">app</span> <span class="o">=</span> <span class="n">webapp2</span><span class="o">.</span><span class="n">WSGIApplication</span><span class="p">([(</span><span class="s1">'/begin-work'</span><span class="p">,</span> <span class="n">BeginWork</span><span class="p">),</span>
<span class="p">(</span><span class="s1">'/'</span><span class="p">,</span> <span class="n">MainPage</span><span class="p">)],</span>
<span class="n">debug</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</code></pre></div>
<p>and specify</p>
<div class="highlight"><pre><span></span><code><span class="nt">handlers</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="nt">url</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/.*</span>
<span class="nt">script</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">main.app</span>
</code></pre></div>
<p>in <code>app.yaml</code>; to use WSGI apps, the App Engine runtime must be <code>python27</code>.</p>
<h2>Client Side Javascript and jQuery</h2>
<p>In the template
<a href="http://code.google.com/p/gae-last-across-the-finish-line/source/browse/templates/main.html"><code>main.html</code></a>
we use <a href="http://jquery.com/">jQuery</a> to make AJAX requests and manage the
CSS for each square in our "quilt". We also define some other Javascript
functions for interacting with the App Engine Channel API. In the
HTML <code><head></code> element we load the
<a href="https://developers.google.com/appengine/docs/python/channel/javascript">Channel Javascript API</a>,
and in the <code><body></code> element we open a channel using the <code>{{ token }}</code> passed
in to the template:</p>
<div class="highlight"><pre><span></span><code><span class="p"><</span><span class="nt">head</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"/_ah/channel/jsapi"</span><span class="p">></</span><span class="nt">script</span><span class="p">></span>
<span class="p"></</span><span class="nt">head</span><span class="p">></span>
<span class="p"><</span><span class="nt">body</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">></span>
<span class="nx">channel</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">goog</span><span class="p">.</span><span class="nx">appengine</span><span class="p">.</span><span class="nx">Channel</span><span class="p">(</span><span class="s1">'{{ token }}'</span><span class="p">);</span>
<span class="nx">socket</span> <span class="o">=</span> <span class="nx">channel</span><span class="p">.</span><span class="nx">open</span><span class="p">();</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">onerror</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Socket error'</span><span class="p">);</span> <span class="p">};</span>
<span class="nx">socket</span><span class="p">.</span><span class="nx">onclose</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Socket closed'</span><span class="p">);</span> <span class="p">};</span>
<span class="p"></</span><span class="nt">script</span><span class="p">></span>
<span class="p"></</span><span class="nt">body</span><span class="p">></span>
</code></pre></div>
<p>In addition to <code>onerror</code> and <code>onclose</code>, we define more complex functions
for the <code>onopen</code> and <code>onmessage</code> callbacks.</p>
<p>First, when the socket has been opened, we send a POST request to
<code>/begin-work</code> to signal that the channel is ready for communication. If
the response indicates that the batch of workers has been initialized
successfully, we call a method <code>setStatus</code> which will reveal the progress
spinner:</p>
<div class="highlight"><pre><span></span><code><span class="nx">socket</span><span class="p">.</span><span class="nx">onopen</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s1">'/begin-work'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">batch_populated</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">setStatus</span><span class="p">(</span><span class="s1">'Loading began'</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">}</span>
</code></pre></div>
<p>As we defined in part one, each <code>SendColor</code> worker sends back a
<a href="https://developers.google.com/appengine/docs/python/channel/overview#Life_of_a_Typical_Channel_Message">message</a>
along the channel representing a row, column pair and a color. On
message receipt, we use these messages to set the background color of
the corresponding square to the color provided:</p>
<div class="highlight"><pre><span></span><code><span class="nx">socket</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">msg</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">squareIndex</span> <span class="o">=</span> <span class="mf">8</span><span class="o">*</span><span class="nx">response</span><span class="p">.</span><span class="nx">row</span> <span class="o">+</span> <span class="nx">response</span><span class="p">.</span><span class="nx">column</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">squareId</span> <span class="o">=</span> <span class="s1">'#square'</span> <span class="o">+</span> <span class="nx">squareIndex</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">squareId</span><span class="p">).</span><span class="nx">css</span><span class="p">(</span><span class="s1">'background-color'</span><span class="p">,</span> <span class="nx">response</span><span class="p">.</span><span class="nx">color</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>As you can see from <code>squareId</code>, each square in the table generated by the
template has an HMTL ID so we can specifically target it.</p>
<h2>Next...</h2>
<p>In the <a href="/2012/09/last-to-cross-finish-line-part-three.html">final post</a>,
we'll define the <code>PopulateBatch</code> function and explore the
<a href="https://developers.google.com/appengine/docs/python/ndb/">ndb models</a> and
<a href="https://developers.google.com/appengine/docs/python/taskqueue/">Task Queue</a>
operations that make it work.</p>Last to Cross the Finish Line: Part One2012-08-27T00:00:00-07:002012-08-27T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-08-27:/2012/08/last-to-cross-finish-line-part-one.html<p>Recently, my colleague
<a href="https://plus.google.com/115640166224745944209">+Fred Sauer</a> and I gave a tech
talk called "Last Across the Finish Line: Asynchronous
<a href="https://developers.google.com/appengine/docs/python/taskqueue/overview">Tasks</a>
with <a href="https://appengine.google.com/">App Engine</a>". This is part one in a
three part series where I will share our
<a href="http://www.forbes.com/pictures/ekij45gdh/learnings/#gallerycontent">learnings</a>
and give some helpful references to the
<a href="https://developers.google.com/appengine/docs/">App Engine documentation</a>.</p>
<h2>Intro</h2>
<p>Before I …</p><p>Recently, my colleague
<a href="https://plus.google.com/115640166224745944209">+Fred Sauer</a> and I gave a tech
talk called "Last Across the Finish Line: Asynchronous
<a href="https://developers.google.com/appengine/docs/python/taskqueue/overview">Tasks</a>
with <a href="https://appengine.google.com/">App Engine</a>". This is part one in a
three part series where I will share our
<a href="http://www.forbes.com/pictures/ekij45gdh/learnings/#gallerycontent">learnings</a>
and give some helpful references to the
<a href="https://developers.google.com/appengine/docs/">App Engine documentation</a>.</p>
<h2>Intro</h2>
<p>Before I dive in, a quick overview of our approach:</p>
<ul>
<li>"Fan out; Fan in" First spread tasks over independent workers; then
gather the results back together</li>
<li>Use task queues to perform background work in parallel<ul>
<li>Tasks have built-in retries</li>
<li>Can respond quickly to the client, making UI more responsive</li>
</ul>
</li>
<li>Operate asynchronously when individual tasks can be executed
independently, hence can be run concurrently<ul>
<li>If tasks are too work intensive to run synchronously, (attempt
to) break work into small independent pieces</li>
</ul>
</li>
<li>Break work into smaller tasks, for example:<ul>
<li>rendering media (sounds, images, video)</li>
<li>retrieving and parsing data from an external service (Google
Drive, Cloud Storage, GitHub, ...)</li>
</ul>
</li>
<li>Keep track of all workers; notify client when work is complete</li>
</ul>
<p>Before talking about the sample, let's check it out in action:</p>
<iframe width="560" height="315" src="//www.youtube.com/embed/tEDDVmgN-iU" frameborder="0" allowfullscreen></iframe>
<p>We are randomly generating a color in a worker and sending it back to
the client to fill in a square in the "quilt". (Thanks to
<a href="https://plus.google.com/103073491679741548297">+Iein Valdez</a> for this term.)
In this example, think of each square as a (most likely more complex)
compute task.</p>
<h2>Application Overview</h2>
<p>The
<a href="https://github.com/GoogleCloudPlatform/appengine-last-across-the-finish-line-python">application</a>
has a simple structure:</p>
<div class="highlight"><pre><span></span><code>gae-last-across-the-finish-line/
|-- app.yaml
|-- display.py
|-- main.py
|-- models.py
+-- templates/
+-- main.html
</code></pre></div>
<p>We'll inspect each of the Python modules <code>display.py</code>, <code>main.py</code> and <code>models.py</code>
individually and explore how they interact with one another. In addition to
this, we'll briefly inspect the HTML and Javascript contained in the template
<code>main.html</code>, to understand how the workers pass messages back to the client.</p>
<p>In this post, I will explain the actual background work we did and
briefly touch on the methods for communicating with the client, but
won't get into client side code or the generic code for running the
workers and watching them all as they cross the finish line. In the
second post, we'll examine the client side code and in the third, we'll
discuss the models that orchestrate the work.</p>
<h2>Workers</h2>
<p>These worker methods are defined in
<a href="http://code.google.com/p/gae-last-across-the-finish-line/source/browse/display.py"><code>display.py</code></a>.
To generate the random colors, we simply choose a hexadecimal digit six
different times and throw a <code>#</code> on at the beginning:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">random</span>
<span class="n">HEX_DIGITS</span> <span class="o">=</span> <span class="s1">'0123456789ABCDEF'</span>
<span class="k">def</span> <span class="nf">RandHexColor</span><span class="p">(</span><span class="n">length</span><span class="o">=</span><span class="mi">6</span><span class="p">):</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">[</span><span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">HEX_DIGITS</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">length</span><span class="p">)]</span>
<span class="k">return</span> <span class="s1">'#'</span> <span class="o">+</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
</code></pre></div>
<p>With <code>RandHexColor</code> in hand, we define a worker that will take a row and column
to be colored and a session ID that will identify the client requesting the
work. This worker will generate a random color and then send it to the
specified client along with the row and column.To pass messages to the
client, we use the
<a href="https://developers.google.com/appengine/docs/python/channel/">Channel API</a>
and serialize our messages using the
<a href="http://docs.python.org/library/json.html"><code>json</code></a> library in Python.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">google.appengine.api</span> <span class="kn">import</span> <span class="n">channel</span>
<span class="k">def</span> <span class="nf">SendColor</span><span class="p">(</span><span class="n">row</span><span class="p">,</span> <span class="n">column</span><span class="p">,</span> <span class="n">session_id</span><span class="p">):</span>
<span class="n">color</span> <span class="o">=</span> <span class="n">RandHexColor</span><span class="p">(</span><span class="n">length</span><span class="o">=</span><span class="mi">6</span><span class="p">)</span>
<span class="n">color_dict</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'row'</span><span class="p">:</span> <span class="n">row</span><span class="p">,</span> <span class="s1">'column'</span><span class="p">:</span> <span class="n">column</span><span class="p">,</span> <span class="s1">'color'</span><span class="p">:</span> <span class="n">color</span><span class="p">}</span>
<span class="n">channel</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="n">session_id</span><span class="p">,</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">color_dict</span><span class="p">))</span>
</code></pre></div>
<h2>Next...</h2>
<p>In the
<a href="/2012/08/last-to-cross-finish-line-part-two.html">next post</a>,
we'll explore the
<a href="https://developers.google.com/appengine/docs/python/tools/webapp/running">WSGI handlers</a>
that run the application and the client side code that handles the
messages from the workers.</p>A Decorator for App Engine Deferred Tasks2012-08-19T00:00:00-07:002012-08-19T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-08-19:/2012/08/a-decorator-for-appengine-deferred-tasks.html<p>I happen to be a big fan of the
<a href="https://developers.google.com/appengine/articles/deferred">deferred library</a>
for both Python runtimes in
<a href="https://developers.google.com/appengine/">Google App Engine</a>.
If an application needs to queue up work, breaking the work into easy to
understand units by writing worker methods and then deferring the work into
tasks is a breeze using …</p><p>I happen to be a big fan of the
<a href="https://developers.google.com/appengine/articles/deferred">deferred library</a>
for both Python runtimes in
<a href="https://developers.google.com/appengine/">Google App Engine</a>.
If an application needs to queue up work, breaking the work into easy to
understand units by writing worker methods and then deferring the work into
tasks is a breeze using the deferred library. For the majority of cases, if fine
grained control over the method of execution is not needed, using the
deferred library is a great (and in my opinion, the correct) abstraction.</p>
<p>Maybe I am just biased because I have made a few
<a href="/2012/03/where-have-i-been.html">changes</a>
to the deferred library over the past few months? One such change I made added a
<a href="http://code.google.com/p/googleappengine/issues/detail?id=6412">feature</a>
that allows a task to fail once without having an impact on subsequent
retries; this can be accomplished by raising a <code>SingularTaskFailure</code>.
Over this weekend, I found that I wanted to use this feature for a
special <a href="#special">type</a> of worker. Since I wanted to utilize this unique
exception, I wanted to make sure that this worker <strong>only</strong> ran in a
deferred task.</p>
<p>Initially I thought I was lost, since any
<a href="http://docs.python.org/library/pickle.html">pickled</a> method wouldn't
directly have access to the
<a href="https://developers.google.com/appengine/docs/python/taskqueue/overview-push#Task_Request_Headers">task queue specific headers</a>
from the request. But luckily, many of these headers persist as
<a href="http://en.wikipedia.org/wiki/Environment_variable">environment variables</a>,
so can be accessed via <code>os.environ</code> or <code>os.getenv</code>, yippee! Being a good little
(Python) boy, I decided to abstract this requirement into a
<a href="http://stackoverflow.com/questions/739654/understanding-python-decorators#1594484">decorator</a>
and let the function do it's own work in peace.</p>
<p>Upon realizing the usefulness of such a decorator, I decided to write
about it, so here it is:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">functools</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.deferred</span> <span class="kn">import</span> <span class="n">defer</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.deferred.deferred</span> <span class="kn">import</span> <span class="n">_DEFAULT_QUEUE</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.deferred.deferred</span> <span class="kn">import</span> <span class="n">_DEFAULT_URL</span>
<span class="n">QUEUE_KEY</span> <span class="o">=</span> <span class="s1">'HTTP_X_APPENGINE_QUEUENAME'</span>
<span class="n">URL_KEY</span> <span class="o">=</span> <span class="s1">'PATH_INFO'</span>
<span class="k">def</span> <span class="nf">DeferredWorkerDecorator</span><span class="p">(</span><span class="n">method</span><span class="p">):</span>
<span class="nd">@functools</span><span class="o">.</span><span class="n">wraps</span><span class="p">(</span><span class="n">method</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">DeferredOnlyMethod</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="n">path_info</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">URL_KEY</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
<span class="k">if</span> <span class="n">path_info</span> <span class="o">!=</span> <span class="n">_DEFAULT_URL</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">EnvironmentError</span><span class="p">(</span><span class="s1">'Wrong path of execution: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">path_info</span><span class="p">))</span>
<span class="n">queue_name</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">QUEUE_KEY</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
<span class="k">if</span> <span class="n">queue_name</span> <span class="o">!=</span> <span class="n">_DEFAULT_QUEUE</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">EnvironmentError</span><span class="p">(</span><span class="s1">'Wrong queue name: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">queue_name</span><span class="p">))</span>
<span class="k">return</span> <span class="n">method</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">return</span> <span class="n">DeferredOnlyMethod</span>
</code></pre></div>
<p>This decorator first checks if the environment variable <code>PATH_INFO</code>
is set to the default value for the deferred queue: <code>/_ah/queue/deferred</code>.
If this is not the case (or if the environment variable is not set), an
<code>EnvironmentError</code> is raised. Then the environment variable
<code>HTTP_X_APPENGINE_QUEUENAME</code> is checked against the name of the default
queue: <code>default</code>. Again, if this is incorrect or unset, an <code>EnvironmentError</code>
is raised. If both these checks pass, the decorated method is called with
its arguments and the value is returned.</p>
<p>To use this decorator:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.deferred</span> <span class="kn">import</span> <span class="n">SingularTaskFailure</span>
<span class="nd">@DeferredWorkerDecorator</span>
<span class="k">def</span> <span class="nf">WorkerMethod</span><span class="p">():</span>
<span class="k">if</span> <span class="n">too_busy</span><span class="p">():</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">SingularTaskFailure</span>
<span class="c1"># do work</span>
<span class="n">WorkerMethod</span><span class="p">()</span> <span class="c1"># This will fail with an EnvironmentError</span>
<span class="n">defer</span><span class="p">(</span><span class="n">WorkerMethod</span><span class="p">)</span> <span class="c1"># This will perform the work, but in it's own task</span>
</code></pre></div>
<p>In case you want to extend this, here is a more "complete" list of some
helpful values that you may be able to retrieve from environment
variables:</p>
<div class="highlight"><pre><span></span><code><span class="n">HTTP_X_APPENGINE_TASKRETRYCOUNT</span>
<span class="n">HTTP_X_APPENGINE_QUEUENAME</span>
<span class="n">HTTP_X_APPENGINE_TASKNAME</span>
<span class="n">HTTP_X_APPENGINE_TASKEXECUTIONCOUNT</span>
<span class="n">HTTP_X_APPENGINE_TASKETA</span>
<span class="n">HTTP_X_APPENGINE_COUNTRY</span>
<span class="n">HTTP_X_APPENGINE_CURRENT_NAMESPACE</span>
<span class="n">PATH_INFO</span>
</code></pre></div>
<div id="special">
<blockquote>
<p><strong>Specialized Worker</strong>: I had two different reasons to raise a
<code>SingularTaskFailure</code>
in my worker. First, I was polling for resources that may not have been
online, so wanted the task to sleep and then restart (after raising the
one time failure). Second, I was using a special sentinel in the
datastore to determine if the current user had any other job in
progress. Again, I wanted to sleep and try again until the current
user's other job had completed.</p>
</blockquote>
</div>Life of π: Continued Fractions and Infinite Series2012-05-17T00:00:00-07:002012-05-17T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-05-17:/2012/05/life-of-continued-fractions-and.html<p>This is from a talk I gave to the
<a href="http://www.math.ucsc.edu/">UC Santa Cruz Math</a> Club back in February.
I have had the slides
<a href="/images/cluttered_desk.jpg">cluttering my desk</a>
since I gave the talk as a reminder of putting them up on the web, and
today I finally cleaned them off!</p>
<p>An interested tidbit …</p><p>This is from a talk I gave to the
<a href="http://www.math.ucsc.edu/">UC Santa Cruz Math</a> Club back in February.
I have had the slides
<a href="/images/cluttered_desk.jpg">cluttering my desk</a>
since I gave the talk as a reminder of putting them up on the web, and
today I finally cleaned them off!</p>
<p>An interested tidbit about these slides: I gave the
<a href="http://www.math.lsa.umich.edu/mathclub/fall2008/103008.pdf">same talk</a> one
other time as an
<a href="http://www.math.lsa.umich.edu/mathclub/">undergraduate</a>. As an
undergraduate I gave the talk the day after a root canal. This February
(at UCSC), one day after the talk I also had a root canal. What's the
moral of the story? Don't give this talk.</p>
<p>No seriously, don't give this talk. Though the fact is cool and the math
is not too bad to grasp, the stuff from slides 106 to 113 goes way over
an audience's collective head just because they have
<a href="/images/sleeping_in_class.jpg">stopped paying attention</a>
at that point. Too many variables!</p>
<p><center><iframe src="//www.slideshare.net/slideshow/embed_code/12977566" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe></center></p>Reverse Calculating An Interest Rate2012-05-15T00:00:00-07:002012-05-15T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-05-15:/2012/05/reverse-calculating-interest-rate.html<p>I was recently playing around with some loan data and only happened to
have the term (or length, or duration) of the loan, the amount of the
recurring payment (in this case monthly) and the remaining principal
owed on the loan. I figured there was an easy way to get …</p><p>I was recently playing around with some loan data and only happened to
have the term (or length, or duration) of the loan, the amount of the
recurring payment (in this case monthly) and the remaining principal
owed on the loan. I figured there was an easy way to get at the interest
rate, but wasn't sure how. After some badgering from my coworker
<a href="https://plus.google.com/104679465567407024302">+Paul</a>, I searched the
web and found a
<a href="http://www.calcamo.net/loancalculator/quickcalculations/loan-rate.php5">tool</a>
from <a href="http://www.calcamo.net/">CALCAmo</a> (a site just for calculating
amortizations).</p>
<p>Problem solved, right? Wrong. I wanted to know why; I had to
<a href="http://knowyourmeme.com/memes/we-need-to-go-deeper">go deeper</a>. So I did a
bit of math and a bit of programming and I was where I needed to be. I'll
break the following down into parts before going on full steam.</p>
<ul>
<li>Break down the amortization schedule in terms of the variables we
have and the one we want</li>
<li>Determine a function we want to find zeros of</li>
<li>Write some code to implement the Newton-Raphson method</li>
<li>Utilize the Newton-Raphson code to find an interest rate</li>
<li>Bonus: Analyze the function to make sure we are right</li>
</ul>
<h2>Step I: Break Down the <a href="http://en.wikipedia.org/wiki/Amortization_schedule">Amortization Schedule</a></h2>
<p>We can do this using the series <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mrow><mo fence="true">{</mo><msub><mi>P</mi><mi>i</mi></msub><mo fence="true">}</mo></mrow><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">\left\{P_i\right\}_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0497em;vertical-align:-0.29969999999999997em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.161964em;"><span style="top:-2.4003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.29969999999999997em;"><span></span></span></span></span></span></span></span></span></span> of
principal owed, which varies over time and will go to zero once paid
off. In this series, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">P_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the principal owed currently and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">P_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the principal owed after <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span>
payments have been made. (Assuming monthly payments, this will be after
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span> months.) If the term is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span></span></span></span> periods,
then we have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mi>T</mi></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">P_T = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>.</p>
<p>We have already introduced the term <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span></span></span></span>; we also need the
value of the recurring (again, usually monthly) payment <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">R,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mpunct">,</span></span></span></span>
the interest rate <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi></mrow><annotation encoding="application/x-tex">r</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span> and the initial principal owed
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mn>0</mn></msub><mo>=</mo><mi>P</mi></mrow><annotation encoding="application/x-tex">P_0 = P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span>.</p>
<h4>Time-Relationship between Principal Values</h4>
<p>If after <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span> periods, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">P_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is owed, then
after one period has elapsed, we will owe <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mi>i</mi></msub><mo>⋅</mo><mi>m</mi></mrow><annotation encoding="application/x-tex">P_i \cdot m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>
where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>=</mo><mi>m</mi><mo stretchy="false">(</mo><mi>r</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">m = m(r)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">m</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mclose">)</span></span></span></span> is some multiplier based on the length of the
term. For example if each period is one month, then we divide our rate by
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>12</mn></mrow><annotation encoding="application/x-tex">12</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">12</span></span></span></span> for the interest and add <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> to note
that we are adding to existing principal:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>m</mi><mo stretchy="false">(</mo><mi>r</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mo>+</mo><mfrac><mi>r</mi><mn>12</mn></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">m(r) = 1 + \frac{r}{12}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">m</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.7935600000000003em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">12</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>In addition to the interest, we will have paid off <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi></mrow><annotation encoding="application/x-tex">R</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span></span> hence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>P</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mi>P</mi><mi>i</mi></msub><mo>⋅</mo><mi>m</mi><mo>−</mo><mi>R</mi><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">P_{i + 1} = P_i \cdot m - R.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.891661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<h4>Formula for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">P_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></h4>
<p>Using this, we can actually determine <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">P_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> strictly in terms
of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo separator="true">,</mo><mi>R</mi></mrow><annotation encoding="application/x-tex">m, R</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">m</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span>. First, note that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><msub><mi>P</mi><mn>2</mn></msub><mo>=</mo><msub><mi>P</mi><mn>1</mn></msub><mo>⋅</mo><mi>m</mi><mo>−</mo><mi>R</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mo stretchy="false">(</mo><msub><mi>P</mi><mn>0</mn></msub><mo>⋅</mo><mi>m</mi><mo>−</mo><mi>R</mi><mo stretchy="false">)</mo><mo>⋅</mo><mi>m</mi><mo>−</mo><mi>R</mi></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mn>2</mn></msup><mo>−</mo><mi>R</mi><mo stretchy="false">(</mo><mi>m</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} P_2 = P_1 \cdot m - R &= (P_0 \cdot m - R) \cdot m - R \\ &= P \cdot m^2 - R(m + 1) \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.024108em;vertical-align:-1.262054em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.762054em;"><span style="top:-3.922054em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span><span style="top:-2.397946em;"><span class="pstrut" style="height:3em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.262054em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.762054em;"><span style="top:-3.922054em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span><span style="top:-2.397946em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mopen">(</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.262054em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mn>0</mn></msub><mo>=</mo><mi>P</mi></mrow><annotation encoding="application/x-tex">P_0 = P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span>. We can show inductively that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><msub><mi>P</mi><mi>i</mi></msub><mo>=</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mi>i</mi></msup><mo>−</mo><mi>R</mi><mo>⋅</mo><munderover><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>0</mn></mrow><mrow><mi>i</mi><mo>−</mo><mn>1</mn></mrow></munderover><msup><mi>m</mi><mi>j</mi></msup><mi mathvariant="normal">.</mi></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle P_i = P \cdot m^i - R \cdot \sum_{j = 0}^{i - 1} m^j.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9579939999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8746639999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:3.2254460000000007em;vertical-align:-1.4137769999999998em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.8116690000000006em;"><span style="top:-1.872331em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">0</span></span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3000050000000005em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.4137769999999998em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.874664em;"><span style="top:-3.1130000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>We already have the base case <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mo>=</mo><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">i = 1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span></span></span></span> by definition.
Assuming it holds for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">i,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">i</span><span class="mpunct">,</span></span></span></span> we see that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><msub><mi>P</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mi>P</mi><mi>i</mi></msub><mo>⋅</mo><mi>m</mi><mo>−</mo><mi>R</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>m</mi><mo>⋅</mo><mrow><mo fence="true">(</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mi>i</mi></msup><mo>−</mo><mi>R</mi><mo>⋅</mo><munderover><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>0</mn></mrow><mrow><mi>i</mi><mo>−</mo><mn>1</mn></mrow></munderover><msup><mi>m</mi><mi>j</mi></msup><mo fence="true">)</mo></mrow><mo>−</mo><mi>R</mi></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msup><mo>−</mo><mi>R</mi><mo>⋅</mo><munderover><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>i</mi></munderover><msup><mi>m</mi><mi>j</mi></msup><mo>−</mo><mi>R</mi><mo separator="true">,</mo></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} P_{i + 1} = P_i \cdot m - R &= m \cdot \left(P \cdot m^i - R \cdot \sum_{j = 0}^{i - 1} m^j\right) - R \\ &= P \cdot m^{i + 1} - R \cdot \sum_{j = 1}^{i} m^j - R, \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:7.050892000000001em;vertical-align:-3.2754460000000005em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.7754460000000005em;"><span style="top:-5.7754460000000005em;"><span class="pstrut" style="height:3.8116690000000006em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span><span style="top:-2.25em;"><span class="pstrut" style="height:3.8116690000000006em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.2754460000000005em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:3.7754460000000005em;"><span style="top:-5.7754460000000005em;"><span class="pstrut" style="height:3.8116690000000006em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size4">(</span></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8746639999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.8116690000000006em;"><span style="top:-1.872331em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">0</span></span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3000050000000005em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.4137769999999998em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.874664em;"><span style="top:-3.1130000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size4">)</span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span><span style="top:-2.25em;"><span class="pstrut" style="height:3.8116690000000006em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.874664em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.8116690000000006em;"><span style="top:-1.872331em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3000050000000005em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.4137769999999998em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.874664em;"><span style="top:-3.1130000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mpunct">,</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.2754460000000005em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>and our induction is complete. (We bump the index <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>j</mi></mrow><annotation encoding="application/x-tex">j</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span></span></span></span> since
we are multiplying each <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>m</mi><mi>j</mi></msup></mrow><annotation encoding="application/x-tex">m^j</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.824664em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.824664em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span></span></span></span></span></span></span> by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>.)
Each term in the series is related to the previous one (except
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mn>0</mn></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">P_0,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> since time can't be negative in this case).</p>
<h2>Step II: Determine a Function we want to find Zeros of</h2>
<p>Since we know <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mi>T</mi></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">P_T = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><msub><mi>P</mi><mi>T</mi></msub><mo>=</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mi>T</mi></msup><mo>−</mo><mi>R</mi><mo>⋅</mo><munderover><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>0</mn></mrow><mrow><mi>T</mi><mo>−</mo><mn>1</mn></mrow></munderover><msup><mi>m</mi><mi>j</mi></msup><mo separator="true">,</mo></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle P_T = P \cdot m^T - R \cdot \sum_{j = 0}^{T - 1} m^j,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9746609999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913309999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:3.2421130000000007em;vertical-align:-1.4137769999999998em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.8283360000000006em;"><span style="top:-1.872331em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">0</span></span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3000050000000005em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.4137769999999998em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.874664em;"><span style="top:-3.1130000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span>
we actually have a polynomial in place that will let us solve for
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> and in so doing, solve for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi></mrow><annotation encoding="application/x-tex">r</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span>.</p>
<p>To make our lives a tad easier, we'll do some rearranging. First, note
that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><munderover><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>0</mn></mrow><mrow><mi>T</mi><mo>−</mo><mn>1</mn></mrow></munderover><msup><mi>m</mi><mi>j</mi></msup><mo>=</mo><msup><mi>m</mi><mrow><mi>T</mi><mo>−</mo><mn>1</mn></mrow></msup><mo>+</mo><mo>⋯</mo><mo>+</mo><mi>m</mi><mo>+</mo><mn>1</mn><mo>=</mo><mfrac><mrow><msup><mi>m</mi><mi>T</mi></msup><mo>−</mo><mn>1</mn></mrow><mrow><mi>m</mi><mo>−</mo><mn>1</mn></mrow></mfrac><mi mathvariant="normal">.</mi></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle \sum_{j = 0}^{T - 1} m^j =m^{T - 1} + \cdots + m + 1 = \frac{m^T - 1}{m - 1}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.2421130000000007em;vertical-align:-1.4137769999999998em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.8283360000000006em;"><span style="top:-1.872331em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span><span class="mrel mtight">=</span><span class="mord mtight">0</span></span></span></span><span style="top:-3.050005em;"><span class="pstrut" style="height:3.05em;"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3000050000000005em;margin-left:0em;"><span class="pstrut" style="height:3.05em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.4137769999999998em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.874664em;"><span style="top:-3.1130000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.974661em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.891331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="minner">⋯</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.287661em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5183309999999999em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>We calculate this sum of a geometric series here, but I'll just refer you to the
<a href="http://en.wikipedia.org/wiki/Geometric_series">Wikipedia page</a> instead. With
this reduction we want to solve</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mn>0</mn><mo>=</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mi>T</mi></msup><mo>−</mo><mi>R</mi><mo>⋅</mo><mfrac><mrow><msup><mi>m</mi><mi>T</mi></msup><mo>−</mo><mn>1</mn></mrow><mrow><mi>m</mi><mo>−</mo><mn>1</mn></mrow></mfrac></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>⟺</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mi>T</mi></msup><mo>⋅</mo><mo stretchy="false">(</mo><mi>m</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo>=</mo><mi>R</mi><mo>⋅</mo><mo stretchy="false">(</mo><msup><mi>m</mi><mi>T</mi></msup><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} & 0 = P \cdot m^T - R \cdot \frac{m^T - 1}{m - 1} \\ & \Longleftrightarrow P \cdot m^T \cdot (m - 1) =R \cdot(m^T - 1). \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:4.138992em;vertical-align:-1.819496em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.319496em;"><span style="top:-4.319496em;"><span class="pstrut" style="height:3.518331em;"></span><span class="mord"></span></span><span style="top:-2.358835em;"><span class="pstrut" style="height:3.518331em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.819496em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.319496em;"><span style="top:-4.319496em;"><span class="pstrut" style="height:3.518331em;"></span><span class="mord"><span class="mord"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913309999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5183309999999999em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-2.358835em;"><span class="pstrut" style="height:3.518331em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⟺</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913309999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913309999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.819496em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>With that, we have accomplished Step II, we have found a function (parameterized
by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo separator="true">,</mo><mi>T</mi></mrow><annotation encoding="application/x-tex">P, T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi></mrow><annotation encoding="application/x-tex">R</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span></span> which we can
use zeros from to find our interest rate:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><msub><mi>f</mi><mrow><mi>P</mi><mo separator="true">,</mo><mi>T</mi><mo separator="true">,</mo><mi>R</mi></mrow></msub><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mi>T</mi></msup><mo>⋅</mo><mo stretchy="false">(</mo><mi>m</mi><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo>−</mo><mi>R</mi><mo>⋅</mo><mo stretchy="false">(</mo><msup><mi>m</mi><mi>T</mi></msup><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mrow><mi>T</mi><mo>+</mo><mn>1</mn></mrow></msup><mo>−</mo><mo stretchy="false">(</mo><mi>P</mi><mo>+</mo><mi>R</mi><mo stretchy="false">)</mo><mo>⋅</mo><msup><mi>m</mi><mi>T</mi></msup><mo>+</mo><mi>R</mi><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} f_{P, T, R}(m) &= P \cdot m^T \cdot (m - 1) -R \cdot(m^T - 1) \\ &= P \cdot m^{T + 1} - (P + R) \cdot m^T + R. \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.102662em;vertical-align:-1.301331em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.801331em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.328331em;"><span style="top:-2.5500000000000003em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.00773em;">R</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">m</span><span class="mclose">)</span></span></span><span style="top:-2.358669em;"><span class="pstrut" style="height:3em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.301331em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.801331em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913309999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913309999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span><span style="top:-2.358669em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.891331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913309999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.301331em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<h2>Step III: Write some code to implement the <a href="http://en.wikipedia.org/wiki/Newton's_method">Newton-Raphson method</a></h2>
<p>We use the Newton-Raphson method to get super-duper-close to a zero of
the function.For in-depth coverage, see the Wikipedia page on the
Newton-Raphson method, but I'll give some cursory coverage below. The
methods used to show that a fixed point is found are not necessary for
the intuition behind the method.</p>
<h4>Intuition behind the method</h4>
<p>For the intuition, assume we know (and can compute) a function
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mpunct">,</span></span></span></span> its derivative <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">f'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> at a value
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span>. Assume there is some zero <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span> nearby
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span>. Since they are close, we can approximate the
slope of the line between the points <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x, f(x))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">))</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>y</mi><mo separator="true">,</mo><mi>f</mi><mo stretchy="false">(</mo><mi>y</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(y, f(y))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">))</span></span></span></span> with the derivative nearby. Since we know
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">x,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">x</span><span class="mpunct">,</span></span></span></span> we use <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">f'(x)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span> and intuit that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mtext>slope</mtext><mo>=</mo><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>y</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><mi>y</mi><mo>−</mo><mi>x</mi></mrow></mfrac><mo>⇒</mo><mi>y</mi><mo>−</mo><mi>x</mi><mo>=</mo><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>y</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">f'(x) = \text{slope} = \frac{f(y) - f(x)}{y - x} \Rightarrow y - x = \frac{f(y) - f(x)}{f'(x)}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord text"><span class="mord">slope</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.30744em;vertical-align:-0.8804400000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804400000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.7777700000000001em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6778919999999999em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>But, since we know that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span> is a zero,
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>y</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">f(y) - f(x) = -f(x)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">−</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span> hence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>y</mi><mo>−</mo><mi>x</mi><mo>=</mo><mfrac><mrow><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow></mfrac><mo>⇒</mo><mi>y</mi><mo>=</mo><mi>x</mi><mo>−</mo><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">y - x = \frac{-f(x)}{f'(x)} \Rightarrow y = x - \frac{f(x)}{f'(x)}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7777700000000001em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6778919999999999em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">−</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6778919999999999em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Using this method, one can start with a given value <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mn>0</mn></msub><mo>=</mo><mi>x</mi></mrow><annotation encoding="application/x-tex">x_0 = x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span>
and compute better and better approximations of a zero via the iteration above
that determines <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span>. We use a sequence to do so:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>x</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo stretchy="false">)</mo></mrow><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo stretchy="false">)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">x_{i + 1} = x_i - \frac{f(x_i)}{f'(x_i)}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.363em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6778919999999999em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>and stop calculating the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">x_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> either after
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">f(x_i)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> is below a preset threshold or after the fineness of
the approximation <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">∣</mo><msub><mi>x</mi><mi>i</mi></msub><mo>−</mo><msub><mi>x</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub><mo fence="true">∣</mo></mrow><annotation encoding="application/x-tex">\left|x_i - x_{i + 1}\right|</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">∣</span></span></span></span></span> goes below a
(likely different) preset threshold. Again, there is much that can be
said about these approximations, but we are trying to accomplish things
today, not theorize.</p>
<p><strong>Programming Newton-Raphson</strong></p>
<p>To perform Newton-Raphson, we'll implement a Python function that takes
the initial guess <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">x_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and the functions
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">f'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span>. We'll also (arbitrarily) stop
after the value <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mi>i</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">f(x_i)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> drops below
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><msup><mn>0</mn><mrow><mo>−</mo><mn>8</mn></mrow></msup></mrow><annotation encoding="application/x-tex">10^{-8}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">8</span></span></span></span></span></span></span></span></span></span></span></span> in absolute value.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">newton_raphson_method</span><span class="p">(</span><span class="n">guess</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">f_prime</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">next_value</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
<span class="k">return</span> <span class="n">value</span> <span class="o">-</span> <span class="n">f</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="o">*</span><span class="mf">1.0</span><span class="o">/</span><span class="n">f_prime</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="n">current</span> <span class="o">=</span> <span class="n">guess</span>
<span class="k">while</span> <span class="nb">abs</span><span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="n">current</span><span class="p">))</span> <span class="o">></span> <span class="mi">10</span><span class="o">**</span><span class="p">(</span><span class="o">-</span><span class="mi">8</span><span class="p">):</span>
<span class="n">current</span> <span class="o">=</span> <span class="n">next_value</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
<span class="k">return</span> <span class="n">current</span>
</code></pre></div>
<p>As you can see, once we have <code>f</code> and <code>f_prime</code>, everything else is easy
because all the work in calculating the next value (via <code>next_value</code>)
is done by the functions.</p>
<h2>Step IV: Utilize the Newton-Raphson code to find an Interest Rate</h2>
<p>We first need to implement
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>f</mi><mrow><mi>P</mi><mo separator="true">,</mo><mi>T</mi><mo separator="true">,</mo><mi>R</mi></mrow></msub><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo><mo>=</mo><mi>P</mi><mo>⋅</mo><msup><mi>m</mi><mrow><mi>T</mi><mo>+</mo><mn>1</mn></mrow></msup><mo>−</mo><mo stretchy="false">(</mo><mi>P</mi><mo>+</mo><mi>R</mi><mo stretchy="false">)</mo><mo>⋅</mo><msup><mi>m</mi><mi>T</mi></msup><mo>+</mo><mi>R</mi></mrow><annotation encoding="application/x-tex">f_{P, T, R}(m) = P \cdot m^{T + 1} - (P + R) \cdot m^T + R</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.328331em;"><span style="top:-2.5500000000000003em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.00773em;">R</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">m</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.924661em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.924661em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8413309999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span></span>
and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msubsup><mi>f</mi><mrow><mi>P</mi><mo separator="true">,</mo><mi>T</mi><mo separator="true">,</mo><mi>R</mi></mrow><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msubsup></mrow><annotation encoding="application/x-tex">f'_{P, T, R}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.163331em;vertical-align:-0.411439em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-2.424669em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.00773em;">R</span></span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.411439em;"><span></span></span></span></span></span></span></span></span></span> in Python. Before doing so, we do a simple
derivative calculation:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msubsup><mi>f</mi><mrow><mi>P</mi><mo separator="true">,</mo><mi>T</mi><mo separator="true">,</mo><mi>R</mi></mrow><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msubsup><mo stretchy="false">(</mo><mi>m</mi><mo stretchy="false">)</mo><mo>=</mo><mi>P</mi><mo>⋅</mo><mo stretchy="false">(</mo><mi>T</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>⋅</mo><msup><mi>m</mi><mi>T</mi></msup><mo>−</mo><mo stretchy="false">(</mo><mi>P</mi><mo>+</mo><mi>R</mi><mo stretchy="false">)</mo><mo>⋅</mo><mi>T</mi><mo>⋅</mo><msup><mi>m</mi><mrow><mi>T</mi><mo>−</mo><mn>1</mn></mrow></msup><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">f_{P, T, R}'(m) = P \cdot (T + 1) \cdot m^T - (P + R) \cdot T \cdot m^{T - 1}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.185em;vertical-align:-0.383108em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-2.4530000000000003em;margin-left:-0.10764em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mpunct mtight">,</span><span class="mord mathnormal mtight" style="margin-right:0.00773em;">R</span></span></span></span><span style="top:-3.1130000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.383108em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">m</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9746609999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8913309999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.891331em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.891331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>With these <a href="http://dictionary.reference.com/browse/formulae">formulae</a> in
hand, we write a function which will spit out the corresponding <code>f</code>
and <code>f_prime</code> given the parameters <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> (<code>principal</code>),
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>T</mi></mrow><annotation encoding="application/x-tex">T</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span></span></span></span> (<code>term</code>) and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>R</mi></mrow><annotation encoding="application/x-tex">R</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.00773em;">R</span></span></span></span> (<code>payment</code>):</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">generate_polynomials</span><span class="p">(</span><span class="n">principal</span><span class="p">,</span> <span class="n">term</span><span class="p">,</span> <span class="n">payment</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">m</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="n">principal</span><span class="o">*</span><span class="p">(</span><span class="n">m</span><span class="o">**</span><span class="p">(</span><span class="n">term</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span> <span class="o">-</span> <span class="p">(</span><span class="n">principal</span> <span class="o">+</span> <span class="n">payment</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">m</span><span class="o">**</span><span class="n">term</span><span class="p">)</span> <span class="o">+</span>
<span class="n">payment</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">f_prime</span><span class="p">(</span><span class="n">m</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="n">principal</span><span class="o">*</span><span class="p">(</span><span class="n">term</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">m</span><span class="o">**</span><span class="n">term</span><span class="p">)</span> <span class="o">-</span>
<span class="p">(</span><span class="n">principal</span> <span class="o">+</span> <span class="n">payment</span><span class="p">)</span><span class="o">*</span><span class="n">term</span><span class="o">*</span><span class="p">(</span><span class="n">m</span><span class="o">**</span><span class="p">(</span><span class="n">term</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)))</span>
<span class="k">return</span> <span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">f_prime</span><span class="p">)</span>
</code></pre></div>
<p>Note that these functions only take a single argument (<code>m</code>), but we are able
to use the other parameters from the parent scope beyond the life of the call
to <code>generate_polynomials</code> due to
<a href="http://en.wikipedia.org/wiki/Closure_(computer_science)">closure</a> in Python.</p>
<p>In order to solve, we need an initial <code>guess</code>, but we need to know the
relationship between <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi></mrow><annotation encoding="application/x-tex">r</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span> before
we can determine what sort of<code>guess</code>makes sense. In addition, once a value for
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> is returned from Newton-Raphson, we need to be able to
turn it into an <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>r</mi></mrow><annotation encoding="application/x-tex">r</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span> value so functions <code>m</code> and <code>m_inverse</code>
should be implemented. For our dummy case here, we'll assume monthly
payments (and compounding):</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">m</span><span class="p">(</span><span class="n">r</span><span class="p">):</span>
<span class="k">return</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">r</span><span class="o">/</span><span class="mf">12.0</span>
<span class="k">def</span> <span class="nf">m_inverse</span><span class="p">(</span><span class="n">m_value</span><span class="p">):</span>
<span class="k">return</span> <span class="mf">12.0</span><span class="o">*</span><span class="p">(</span><span class="n">m_value</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<p>Using these, and assuming that an interest rate of <strong>10%</strong> is a good
guess, we can put all the pieces together:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">solve_for_interest_rate</span><span class="p">(</span><span class="n">principal</span><span class="p">,</span> <span class="n">term</span><span class="p">,</span> <span class="n">payment</span><span class="p">,</span> <span class="n">m</span><span class="p">,</span> <span class="n">m_inverse</span><span class="p">):</span>
<span class="n">f</span><span class="p">,</span> <span class="n">f_prime</span> <span class="o">=</span> <span class="n">generate_polynomials</span><span class="p">(</span><span class="n">principal</span><span class="p">,</span> <span class="n">term</span><span class="p">,</span> <span class="n">payment</span><span class="p">)</span>
<span class="n">guess_m</span> <span class="o">=</span> <span class="n">m</span><span class="p">(</span><span class="mf">0.10</span><span class="p">)</span> <span class="c1"># ten percent as a decimal</span>
<span class="n">m_value</span> <span class="o">=</span> <span class="n">newton_raphson_method</span><span class="p">(</span><span class="n">guess_m</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">f_prime</span><span class="p">)</span>
<span class="k">return</span> <span class="n">m_inverse</span><span class="p">(</span><span class="n">m_value</span><span class="p">)</span>
</code></pre></div>
<p>To check that this makes sense, let's plug in some values. Using the
<a href="http://www.bankrate.com/calculators/mortgages/mortgage-calculator.aspx">bankrate.com loan calculator</a>,
if we have a 30-year loan (with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>12</mn><mo>⋅</mo><mn>30</mn><mo>=</mo><mn>360</mn></mrow><annotation encoding="application/x-tex">12 \cdot 30 = 360</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">12</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">30</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">360</span></span></span></span> months of
payments) of $100,000 with an interest rate of 7%, the monthly payment
would be $665.30. Plugging this into our pipeline:</p>
<div class="highlight"><pre><span></span><code><span class="o">>>></span> <span class="n">principal</span> <span class="o">=</span> <span class="mi">100000</span>
<span class="o">>>></span> <span class="n">term</span> <span class="o">=</span> <span class="mi">360</span>
<span class="o">>>></span> <span class="n">payment</span> <span class="o">=</span> <span class="mf">665.30</span>
<span class="o">>>></span> <span class="n">solve_for_interest_rate</span><span class="p">(</span><span class="n">principal</span><span class="p">,</span> <span class="n">term</span><span class="p">,</span> <span class="n">payment</span><span class="p">,</span> <span class="n">m</span><span class="p">,</span> <span class="n">m_inverse</span><span class="p">)</span>
<span class="mf">0.0699996284703</span>
</code></pre></div>
<p>And we see the rate of 7% is approximated quite well!</p>
<h2>Bonus: Analyze the function to make sure we are right</h2>
<p>Coming soon. We will analyze the derivative and concavity to make sure
that our guess yield the correct (and unique) zero.</p>Silly Pranks on your Friends2012-04-07T00:00:00-07:002012-04-07T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-04-07:/2012/04/silly-pranks-on-your-friends.html<h2>Disclaimer: These are silly little pranks, but I don't encourage messing with someone's computing environment without letting them know you have done so.</h2>
<h3>First Prank:</h3>
<p>I have a friend who really likes to read
<a href="http://people.com/">people.com</a>, so I figured I would "enrich" her life
a bit with another source of …</p><h2>Disclaimer: These are silly little pranks, but I don't encourage messing with someone's computing environment without letting them know you have done so.</h2>
<h3>First Prank:</h3>
<p>I have a friend who really likes to read
<a href="http://people.com/">people.com</a>, so I figured I would "enrich" her life
a bit with another source of daily news :)</p>
<p>I decided to play around with her
<a href="http://en.wikipedia.org/wiki/Hosts_(file)#Purpose">hosts file</a>, so that when
she visited <a href="http://people.com/">people.com</a>, she really got the
<a href="http://nytimes.com/">New York Times</a> (the realest news I could think of at
that time, though there are plenty of fine candidates).</p>
<p>To quote the Wikipedia article on <code>hosts</code> files:</p>
<blockquote>
<p>The hosts file...assists in addressing network nodes in a computer
network. It is a common part of an operating system's Internet
Protocol (IP) implementation, and serves the function of translating
human-friendly hostnames into numeric protocol addresses, called IP
addresses, that identify and locate a host in an IP network.</p>
</blockquote>
<p>More <a href="http://www.justincarmony.com/blog/2011/07/27/mac-os-x-lion-etc-hosts-bugs-and-dns-resolution/">importantly</a>:</p>
<blockquote>
<p>the <code>/etc/hosts</code> file...allows you to add entries that traditionally
your computer will look up first before trying your server DNS.</p>
</blockquote>
<p>This means that even though the
<a href="http://en.wikipedia.org/wiki/Domain_Name_System">DNS Lookup</a> provided by her
<a href="http://en.wikipedia.org/wiki/Internet_service_provider">ISP</a> could
resolve <code>people.com</code>, her browser would get an
<a href="http://en.wikipedia.org/wiki/IP_address">IP address</a> from the hosts file
first and hence will render the New York Times page for
<a href="http://people.com/">people.com</a>.</p>
<p>The first step to do this was to find the IP address for the replacement
site:</p>
<div class="highlight"><pre><span></span><code>$ ping www.nytimes.com
PING www.nytimes.com <span class="o">(</span><span class="m">199</span>.239.136.200<span class="o">)</span>: <span class="m">56</span> data bytes
<span class="m">64</span> bytes from <span class="m">199</span>.239.136.200: <span class="nv">icmp_seq</span><span class="o">=</span><span class="m">0</span> <span class="nv">ttl</span><span class="o">=</span><span class="m">64</span> <span class="nv">time</span><span class="o">=</span><span class="m">0</span>.062 ms
<span class="m">64</span> bytes from <span class="m">199</span>.239.136.200: <span class="nv">icmp_seq</span><span class="o">=</span><span class="m">1</span> <span class="nv">ttl</span><span class="o">=</span><span class="m">64</span> <span class="nv">time</span><span class="o">=</span><span class="m">0</span>.054 ms
...
</code></pre></div>
<p>For the second (and final) step, I just needed to add an entry to the
<code>hosts</code> file. After
<a href="http://en.wikipedia.org/wiki/Hosts_(file)#Location_in_the_file_system">locating</a>
the file on her Macbook in <code>/etc/hosts</code>, I updated the contents:</p>
<div class="highlight"><pre><span></span><code>##
# <span class="nv">Host</span> <span class="nv">Database</span>
#
# <span class="nv">localhost</span> <span class="nv">is</span> <span class="nv">used</span> <span class="nv">to</span> <span class="nv">configure</span> <span class="nv">the</span> <span class="nv">loopback</span> <span class="nv">interface</span>
# <span class="nv">when</span> <span class="nv">the</span> <span class="nv">system</span> <span class="nv">is</span> <span class="nv">booting</span>. <span class="k">Do</span> <span class="nv">not</span> <span class="nv">change</span> <span class="nv">this</span> <span class="nv">entry</span>.
##
<span class="mi">127</span>.<span class="mi">0</span>.<span class="mi">0</span>.<span class="mi">1</span> <span class="nv">localhost</span>
<span class="mi">255</span>.<span class="mi">255</span>.<span class="mi">255</span>.<span class="mi">255</span> <span class="nv">broadcasthost</span>
::<span class="mi">1</span> <span class="nv">localhost</span>
<span class="nv">fe80</span>::<span class="mi">1</span><span class="o">%</span><span class="nv">lo0</span> <span class="nv">localhost</span>
<span class="mi">199</span>.<span class="mi">239</span>.<span class="mi">136</span>.<span class="mi">200</span> <span class="nv">people</span>.<span class="nv">com</span> # <span class="nv">New</span> <span class="nv">entry</span>
</code></pre></div>
<p>Voilà! With that, the prank was complete and the next time she visited
<a href="http://people.com/">people.com</a>, the got the contents of
<a href="http://nytimes.com/">nytimes.com</a> in her browser.</p>
<h3>Second Prank coming soon.</h3>Where have I been?2012-03-28T00:00:00-07:002012-03-28T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2012-03-28:/2012/03/where-have-i-been.html<p>Well, it's been a bit crazy and I haven't written a blog post in ages. I
have several brewing, but had just been too busy at work (and a ton of
travel for personal fun) to really have the excess time to write.</p>
<p>This return post will not have much …</p><p>Well, it's been a bit crazy and I haven't written a blog post in ages. I
have several brewing, but had just been too busy at work (and a ton of
travel for personal fun) to really have the excess time to write.</p>
<p>This return post will not have much content but will announce that I'm a
big boy now.</p>
<p>In the 1.6.3 release of the App Engine SDK (and hence runtime), three
nifty changes of mine were included. Two of them even made the
<a href="http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes#Version_1.6.3_-_February_28,_2012">Release Notes</a>:</p>
<ul>
<li>Code that inherits from the deferred library's <code>TaskHandler</code>
can now define custom handling of exceptions.<ul>
<li>See issue <a href="http://code.google.com/p/googleappengine/issues/detail?id=6478">6478</a></li>
</ul>
</li>
<li>Fixed an issue so that a deferred task retries like a push queue task
when using the <code>SingularTaskFailure</code> exception:<ul>
<li>See issue <a href="http://code.google.com/p/googleappengine/issues/detail?id=6412">6412</a></li>
</ul>
</li>
</ul>
<p>In addition, the one that was most confusing to fix didn't make it into
any set of Release Notes, but I "closed" the
<a href="http://stackoverflow.com/questions/8304854/gql-query-with-key-in-list-of-keys">issue</a>
that I originally opened on StackOverflow. Checkout the
<a href="http://code.google.com/p/googleappengine/source/diff?spec=svn241&r=241&format=side&path=/trunk/python/google/appengine/ext/gql/__init__.py&old_path=/trunk/python/google/appengine/ext/gql/__init__.py">diff</a>
to see the details. I'll follow up with a summary of each of the fixes in a
later post.</p>A Python Metaclass for "extra bad" errors in Google App Engine2011-11-30T00:00:00-08:002011-11-30T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-11-30:/2011/11/python-metaclass-for-extra-bad-errors.html<p>So now here we are, having tried to
<a href="/2011/11/handling-errors-in-google-app-engineand.html">handle errors in Google App Engine...and failed</a>
all because silly <code>DeadlineExceededError</code>
<a href="https://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/runtime/__init__.py?r=491#33">jumps over</a>
<code>Exception</code> in the inheritance chain and goes right for <code>BaseException</code>.
How can we catch these in our handlers while staying
<a href="http://docs.python.org/glossary.html#term-pythonic">Pythonic</a>?</p>
<p>First and foremost, in the case of …</p><p>So now here we are, having tried to
<a href="/2011/11/handling-errors-in-google-app-engineand.html">handle errors in Google App Engine...and failed</a>
all because silly <code>DeadlineExceededError</code>
<a href="https://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/runtime/__init__.py?r=491#33">jumps over</a>
<code>Exception</code> in the inheritance chain and goes right for <code>BaseException</code>.
How can we catch these in our handlers while staying
<a href="http://docs.python.org/glossary.html#term-pythonic">Pythonic</a>?</p>
<p>First and foremost, in the case of a timeout, we need to explicitly
catch a <code>DeadlineExceededError</code>. To do so, we can use a
<a href="http://stackoverflow.com/questions/739654/understanding-python-decorators#1594484">decorator</a>
(hey, that's Pythonic) in each and every handler for each and every HTTP
verb. (Again,
<a href="/images/prepare-yourself.jpg">prepare yourselves</a>,
a bunch of code is about to happen. See the necessary <a href="#imports">imports</a>
at the bottom of the post.)</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">deadline_decorator</span><span class="p">(</span><span class="n">method</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">wrapped_method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">except</span> <span class="n">DeadlineExceededError</span><span class="p">:</span>
<span class="n">traceback_info</span> <span class="o">=</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">format_exception</span><span class="p">(</span><span class="o">*</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()))</span>
<span class="n">email_admins</span><span class="p">(</span><span class="n">traceback_info</span><span class="p">,</span> <span class="n">defer_now</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">serve_500</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="n">wrapped_method</span>
</code></pre></div>
<p>Unfortunately, having to manually decorate
<a href="http://knowyourmeme.com/memes/x-all-the-y">all the functions</a>
is not so Pythonic. At this point I was stuck and wanted to give up, but
<a href="https://plus.google.com/u/0/114760865724135687241/posts/GJjXjq5zXhU">asked for some advice</a>
on <a href="http://www.google.com/+">G+</a> and actually got what I needed from the
all knowing
<a href="https://plus.google.com/u/0/118327176775959145936/posts">Ali Afshar</a>.
What did I need?</p>
<blockquote>
<p><a href="http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python#6581949">Metaclasses</a>.</p>
</blockquote>
<p>Before showing the super simple metaclass I wrote, you need to know one
thing from StackOverflow user
<a href="http://stackoverflow.com/users/9951/kevin-samuel">Kevin Samuel</a>:</p>
<blockquote>
<p>The main purpose of a metaclass is to change the class automatically,
when it's created.</p>
</blockquote>
<p>With the <code>__new__</code>
method, the <code>type</code>
object in Python actually constructs a class (which is also an object)
by taking into account the name of the class, the parents (or bases) and
the class attritubutes. So, we can make a metaclass by subclassing <code>type</code> and overriding
<code>__new__</code>:</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">DecorateHttpVerbsMetaclass</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">cls_attr</span><span class="p">):</span>
<span class="n">verbs</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'get'</span><span class="p">,</span> <span class="s1">'post'</span><span class="p">,</span> <span class="s1">'put'</span><span class="p">,</span> <span class="s1">'delete'</span><span class="p">]</span>
<span class="k">for</span> <span class="n">verb</span> <span class="ow">in</span> <span class="n">verbs</span><span class="p">:</span>
<span class="k">if</span> <span class="n">verb</span> <span class="ow">in</span> <span class="n">cls_attr</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">cls_attr</span><span class="p">[</span><span class="n">verb</span><span class="p">],</span> <span class="n">function</span><span class="p">):</span>
<span class="n">cls_attr</span><span class="p">[</span><span class="n">verb</span><span class="p">]</span> <span class="o">=</span> <span class="n">deadline_decorator</span><span class="p">(</span><span class="n">cls_attr</span><span class="p">[</span><span class="n">verb</span><span class="p">])</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">DecorateHttpVerbsMetaclass</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span>
<span class="n">bases</span><span class="p">,</span> <span class="n">cls_attr</span><span class="p">)</span>
</code></pre></div>
<p>In <code>DecorateHttpVerbsMetaclass</code>,
we look for four (of the nine) HTTP
<a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods">verbs</a>,
because heck, only seven are supported in
<a href="http://code.google.com/appengine/docs/python/tools/webapp/requesthandlerclass.html"><code>RequestHandler</code></a>,
and we're not that crazy. If the class has one of the verbs as an
attribute <strong>and if</strong> the attribute is a function, we
decorate it with <code>deadline_decorator</code>.</p>
<p>Now, we can rewrite our subclass of <code>RequestHandler</code>
with one extra line:</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">ExtendedHandler</span><span class="p">(</span><span class="n">RequestHandler</span><span class="p">):</span>
<span class="n">__metaclass__</span> <span class="o">=</span> <span class="n">DecorateHttpVerbsMetaclass</span>
<span class="k">def</span> <span class="nf">handle_exception</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exception</span><span class="p">,</span> <span class="n">debug_mode</span><span class="p">):</span>
<span class="n">traceback_info</span> <span class="o">=</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">format_exception</span><span class="p">(</span><span class="o">*</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()))</span>
<span class="n">email_admins</span><span class="p">(</span><span class="n">traceback_info</span><span class="p">,</span> <span class="n">defer_now</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">serve_500</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
</code></pre></div>
<p>By doing this, when the <strong>class</strong> <code>ExtendedHandler</code>
is built (as an <strong>object</strong>), all of its attributes and all of its
parent classes (or bases) attributes are checked and possibly updated by
our metaclass.</p>
<p>And now you and James Nekbehrd can feel
<a href="http://www.youtube.com/watch?v=NisCkxU544c">like a boss</a> when your app
handles errors.</p>
<h2 id="imports">Imports:</h2>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">google.appengine.api</span> <span class="kn">import</span> <span class="n">mail</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.deferred</span> <span class="kn">import</span> <span class="n">defer</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.webapp</span> <span class="kn">import</span> <span class="n">RequestHandler</span>
<span class="kn">from</span> <span class="nn">google.appengine.runtime</span> <span class="kn">import</span> <span class="n">DeadlineExceededError</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">traceback</span> <span class="kn">import</span> <span class="n">format_exception</span>
<span class="kn">from</span> <span class="nn">SOME_APP_SPECIFIC_LIBRARY</span> <span class="kn">import</span> <span class="n">serve_500</span>
<span class="kn">from</span> <span class="nn">LAST_POST</span> <span class="kn">import</span> <span class="n">email_admins</span>
</code></pre></div>
<h4>Pythonic:</h4>
<blockquote>
<p>An idea or piece of code which closely follows the most common idioms
of the Python language, rather than implementing code using concepts
common to other languages.</p>
</blockquote>
<h4>Notes:</h4>
<ul>
<li>
<p>Using <code>grep -r "Exception)" . | grep "class "</code>
I have convinced myself (for now) that the only errors App Engine will throw
that do not inherit from <code>Exception</code> are <code>DeadlineExceededError</code>,
<code>SystemExit</code>, and <code>KeyboardInterrupt</code> so that is why I only catch the
timeout.</p>
</li>
<li>
<p>You can also use <code>webapp2</code> to
<a href="http://stackoverflow.com/questions/6853257/how-can-i-setup-a-global-deadlineexceedederror-handler">catch 500 errors</a>,
even when <code>handle_exception</code> fails to catch them.</p>
</li>
</ul>
<h4>Disclaimer: <span style="font-weight: normal;">Just because you know what a metaclass is doesn't mean you should use one.</span></h4>
<ul>
<li><em>"Don't do stuff like this though, what is your use case?"</em> - Ali Afshar</li>
<li><em>"Metaclasses are deeper magic than 99% of users should ever worry
about. If you wonder whether you need them, you don't (the people
who actually need them know with certainty that they need them, and
don't need an explanation about why)."</em> - Python Guru Tim Peters</li>
<li><em>"The main use case for a metaclass is creating an API."</em> -Kevin
Samuel</li>
</ul>Handling errors in Google App Engine...and failing2011-11-27T00:00:00-08:002011-11-27T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-11-27:/2011/11/handling-errors-in-google-app-engineand.html<p>After spending a nontrivial amount of my nights and weekends working on
an App Engine app, I wanted a good way to monitor the logs without
checking in on them every day. After a particularly frustrating weekend
of updates that exposed unnoticed bugs that had yet to be triggered by …</p><p>After spending a nontrivial amount of my nights and weekends working on
an App Engine app, I wanted a good way to monitor the logs without
checking in on them every day. After a particularly frustrating weekend
of updates that exposed unnoticed bugs that had yet to be triggered by
the app, I set out to find such a way. I set out to find a
<a href="http://docs.python.org/glossary.html#term-pythonic">Pythonic</a> way.</p>
<p>Since I knew the
<a href="http://code.google.com/appengine/docs/python/mail/">App Engine Mail API</a> was
super easy to configure, I figured I would just
email myself every time there was an exception, before serving my
default 500 error page. To do so, I just needed to subclass the default
<a href="http://code.google.com/appengine/docs/python/tools/webapp/requesthandlerclass.html"><code>RequestHandler</code></a>
with my own
<a href="http://code.google.com/appengine/docs/python/tools/webapp/requesthandlerclass.html#RequestHandler_handle_exception"><code>handle_exception</code></a>
method. (OK, <a href="/images/prepare-yourself.jpg">prepare yourselves</a>,
a bunch of code is about to happen. See the necessary
<a href="#imports">imports</a> at the bottom of the post.)</p>
<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">ExtendedHandler</span><span class="p">(</span><span class="n">RequestHandler</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">handle_exception</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exception</span><span class="p">,</span> <span class="n">debug_mode</span><span class="p">):</span>
<span class="n">traceback_info</span> <span class="o">=</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">format_exception</span><span class="p">(</span><span class="o">*</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()))</span>
<span class="n">email_admins</span><span class="p">(</span><span class="n">traceback_info</span><span class="p">,</span> <span class="n">defer_now</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">serve_500</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
</code></pre></div>
<p>Awesome! By making all my handlers inherit from <code>ExtendedHandler</code>,
I can use the native Python modules <code>traceback</code> and <code>sys</code>
to get the traceback and my handy dandy</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">email_admins</span><span class="p">(</span><span class="n">error_msg</span><span class="p">,</span> <span class="n">defer_now</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="k">if</span> <span class="n">defer_now</span><span class="p">:</span>
<span class="n">defer</span><span class="p">(</span><span class="n">email_admins</span><span class="p">,</span> <span class="n">error_msg</span><span class="p">,</span> <span class="n">defer_now</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">sender</span> <span class="o">=</span> <span class="s1">'YOUR APP Errors <errors@your_app_id_here.appspotmail.com>'</span>
<span class="n">to</span> <span class="o">=</span> <span class="s1">'Robert Admin <bob@example.com>, James Nekbehrd <jim@example.com>'</span>
<span class="n">subject</span> <span class="o">=</span> <span class="s1">'YOUR APP Error: Admin Notify'</span>
<span class="n">body</span> <span class="o">=</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s1">'Dearest Admin,'</span><span class="p">,</span>
<span class="s1">''</span><span class="p">,</span>
<span class="s1">'An error has occurred in YOUR APP:'</span><span class="p">,</span>
<span class="n">error_msg</span><span class="p">,</span>
<span class="s1">''</span><span class="p">])</span>
<span class="n">mail</span><span class="o">.</span><span class="n">send_mail</span><span class="p">(</span><span class="n">sender</span><span class="o">=</span><span class="n">sender</span><span class="p">,</span> <span class="n">to</span><span class="o">=</span><span class="n">to</span><span class="p">,</span>
<span class="n">subject</span><span class="o">=</span><span class="n">subject</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="n">body</span><span class="p">)</span>
</code></pre></div>
<p>to send out the email in the
<a href="http://code.google.com/appengine/articles/deferred.html">deferred queue</a>
as not to hold up the handler serving the page.
Mission accomplished, right? <strong>WRONG!</strong></p>
<p>Unfortunately, <code>handle_exception</code>
<a href="http://code.google.com/p/googleappengine/issues/detail?id=2110">only handles</a>
the "right" kind of exceptions. That is, exceptions which inherit
directly from Python's <code>Exception</code>.
From the <a href="/images/horse.jpg">horse</a>'s
<a href="http://docs.python.org/tutorial/errors.html#user-defined-exceptions">mouth</a>:</p>
<blockquote>
<p>Exceptions should typically be derived from the
<a href="http://docs.python.org/library/exceptions.html#exceptions.Exception"><code>Exception</code></a>
class, either directly or indirectly.</p>
</blockquote>
<p>But. <a href="http://www.youtube.com/watch?v=a1Y73sPHKxw">But</a>! If the app fails
because a request times out, a <code>DeadlineExceededError</code> is thrown and
<code>handle_exception</code> falls on its face. Why? Because <code>DeadlineExceededError</code>
<a href="https://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/runtime/__init__.py?r=491#33">inherits</a>
directly from <code>Exception</code>'s parent class:<code>BaseException</code>.</p>
<p>It's OK little ones, in my
<a href="/2011/11/python-metaclass-for-extra-bad-errors.html">next post</a>
I explain how I did it while keeping my code Pythonic by using
<a href="http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python#6581949">metaclasses</a>.</p>
<h2 id="imports">Imports:</h2>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">google.appengine.api</span> <span class="kn">import</span> <span class="n">mail</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.deferred</span> <span class="kn">import</span> <span class="n">defer</span>
<span class="kn">from</span> <span class="nn">google.appengine.ext.webapp</span> <span class="kn">import</span> <span class="n">RequestHandler</span>
<span class="kn">import</span> <span class="nn">sysfrom</span> <span class="n">traceback</span> <span class="kn">import</span> <span class="nn">format_exception</span>
<span class="kn">from</span> <span class="nn">SOME_APP_SPECIFIC_LIBRARY</span> <span class="kn">import</span> <span class="n">serve_500</span>
</code></pre></div>
<h4>Pythonic:</h4>
<blockquote>
<p>An idea or piece of code which closely follows the most common idioms
of the Python language, rather than implementing code using concepts
common to other languages.</p>
</blockquote>
<h4>Deferred Queue:</h4>
<p>Make sure to enable the deferred library in your <code>app.yaml</code>
by using <code>deferred: on</code> in your builtins.</p>Quick and Dirty: Santa's Coming2011-11-17T00:00:00-08:002011-11-17T00:00:00-08:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-11-17:/2011/11/quick-and-dirty-santas-coming.html<p>I have been wanting to write a post for awhile, but was travelling for a
<a href="https://sites.google.com/site/barcelonadevfest/">work event</a> and while
on the road I decided to be lazy.</p>
<p>Since I just so happen to use a few
<a href="http://code.google.com/apis/gdata/">GData APIs</a> occasionally in my day to day
work, most of the post ideas …</p><p>I have been wanting to write a post for awhile, but was travelling for a
<a href="https://sites.google.com/site/barcelonadevfest/">work event</a> and while
on the road I decided to be lazy.</p>
<p>Since I just so happen to use a few
<a href="http://code.google.com/apis/gdata/">GData APIs</a> occasionally in my day to day
work, most of the post ideas revolve around quirky things I have done or
want to do with the APIs. Also, due to my obscene love for Python, all
my mashups seem to end up using the
<a href="http://code.google.com/p/gdata-python-client/">Python Client for GData</a>.</p>
<h4>Back-story:</h4>
<p>As I was finalizing travel and gifts for my winter holiday back home, I called
an old friend to let him know I'd be home in 40 days. After relaying this
information to a few other people, I noted to my girlfriend that it would be
nice if a computer would remind me of the count every day. This is where this
quick and dirty pair of scripts come in to remind me when Santa is coming.</p>
<h4>Pre-work — Account Settings:</h4>
<p>To allow an app to make requests on my behalf, I signed up to
<a href="https://accounts.google.com/ManageDomains">Manage my Domain</a>
for use with Google Apps, etc. For illustration purposes, let's say I used
<code>http://example.com</code> (in reality, I used a pre-existing App of mine, I really
just needed an OAuth token for one time use, no real safety concerns there).
After adding this domain in the management page, I am able to get my
<strong>OAuth Consumer Key</strong> and <strong>OAuth Consumer Secret</strong> which we'll say are
<code>EXAMPLE_KEY</code> and <code>EXAMPLE_SECRET</code> in this example. Also in the management page,
I set my <strong>OAuth 2.0 Redirect URIs</strong> and made sure my app can serve that page
(even if it is a 404). Again for illustration, let's pretend I used
<code>http://example.com/verify</code>.</p>
<p>After doing this settings pre-work, I have two scripts to do the work for me.</p>
<h2>First script — get the OAuth Token:</h2>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">gdata.calendar.client</span>
<span class="kn">import</span> <span class="nn">gdata.gauth</span>
<span class="n">gcal</span> <span class="o">=</span> <span class="n">gdata</span><span class="o">.</span><span class="n">calendar</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">CalendarClient</span><span class="p">()</span>
<span class="n">oauth_callback</span> <span class="o">=</span> <span class="s1">'http://example.com/verify'</span>
<span class="n">scopes</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'https://www.google.com/calendar/feeds/'</span><span class="p">]</span>
<span class="n">consumer_key</span> <span class="o">=</span> <span class="s1">'EXAMPLE_KEY'</span>
<span class="n">consumer_secret</span> <span class="o">=</span> <span class="s1">'EXAMPLE_SECRET'</span>
<span class="n">request_token</span> <span class="o">=</span> <span class="n">gcal</span><span class="o">.</span><span class="n">get_oauth_token</span><span class="p">(</span><span class="n">scopes</span><span class="p">,</span> <span class="n">oauth_callback</span><span class="p">,</span>
<span class="n">consumer_key</span><span class="p">,</span> <span class="n">consumer_secret</span><span class="p">)</span>
<span class="n">out_str</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'Please visit https://www.google.com/accounts/OAuthAuthorize'</span>
<span class="s1">'Token?hd=default&oauth_token=</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">request_token</span><span class="o">.</span><span class="n">token</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">out_str</span>
<span class="n">follow</span> <span class="o">=</span> <span class="n">raw_input</span><span class="p">(</span><span class="s1">'Please entry the follow link after authorizing:</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="n">gdata</span><span class="o">.</span><span class="n">gauth</span><span class="o">.</span><span class="n">authorize_request_token</span><span class="p">(</span><span class="n">request_token</span><span class="p">,</span> <span class="n">follow</span><span class="p">)</span>
<span class="n">gcal</span><span class="o">.</span><span class="n">auth_token</span> <span class="o">=</span> <span class="n">gcal</span><span class="o">.</span><span class="n">get_access_token</span><span class="p">(</span><span class="n">request_token</span><span class="p">)</span>
<span class="nb">print</span> <span class="s1">'TOKEN:'</span><span class="p">,</span> <span class="n">gcal</span><span class="o">.</span><span class="n">auth_token</span><span class="o">.</span><span class="n">token</span>
<span class="nb">print</span> <span class="s1">'TOKEN_SECRET:'</span><span class="p">,</span> <span class="n">gcal</span><span class="o">.</span><span class="n">auth_token</span><span class="o">.</span><span class="n">token_secret</span>
</code></pre></div>
<p>This script "spoofs" the OAuth handshake by asking the user (me) to go
directly to the
<a href="https://www.google.com/accounts/OAuthAuthorizeToken">OAuth Authorize page</a>.
After doing so and authorizing the App, I am redirected to
<code>http://example.com/verify</code> with query parameters for <code>oauth_verifier</code>
and <code>oauth_token</code>. These are then used by the <code>gauth</code>
section of the GData library to finish the OAuth handshake. Once the
handshake is complete, the script prints out a necessary token and token
secret to be used by the second script. I would advise piping the output
to a file, augmenting the script to write them to a file, or writing
these down (this is a joke, please don't write down 40 plus character
goop that was <strong>produced by your computer</strong>). For the next script,
let's pretend our token is <code>FAKE_TOKEN</code> and our token secret is
<code>FAKE_TOKEN_SECRET</code>.</p>
<h4>Second script — insert the events:</h4>
<div class="highlight"><pre><span></span><code><span class="c1"># General libraries</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">date</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">timedelta</span>
<span class="c1"># Third-party libraries</span>
<span class="kn">import</span> <span class="nn">atom</span>
<span class="kn">import</span> <span class="nn">gdata.gauth</span>
<span class="kn">import</span> <span class="nn">gdata.calendar.client</span>
<span class="kn">import</span> <span class="nn">gdata.calendar.data</span>
<span class="n">gcal</span> <span class="o">=</span> <span class="n">gdata</span><span class="o">.</span><span class="n">calendar</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">CalendarClient</span><span class="p">()</span>
<span class="n">auth_token</span> <span class="o">=</span> <span class="n">gdata</span><span class="o">.</span><span class="n">gauth</span><span class="o">.</span><span class="n">OAuthHmacToken</span><span class="p">(</span><span class="n">consumer_key</span><span class="o">=</span><span class="s1">'EXAMPLE_KEY'</span><span class="p">,</span>
<span class="n">consumer_secret</span><span class="o">=</span><span class="s1">'EXAMPLE_SECRET'</span><span class="p">,</span>
<span class="n">token</span><span class="o">=</span><span class="s1">'FAKE_TOKEN'</span><span class="p">,</span>
<span class="n">token_secret</span><span class="o">=</span><span class="s1">'FAKE_TOKEN_SECRET'</span><span class="p">,</span>
<span class="n">auth_state</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
<span class="n">gcal</span><span class="o">.</span><span class="n">auth_token</span> <span class="o">=</span> <span class="n">auth_token</span>
<span class="n">today</span> <span class="o">=</span> <span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">()</span>
<span class="n">days_left</span> <span class="o">=</span> <span class="p">(</span><span class="n">date</span><span class="p">(</span><span class="n">year</span><span class="o">=</span><span class="mi">2011</span><span class="p">,</span> <span class="n">month</span><span class="o">=</span><span class="mi">12</span><span class="p">,</span> <span class="n">day</span><span class="o">=</span><span class="mi">23</span><span class="p">)</span> <span class="o">-</span> <span class="n">today</span><span class="p">)</span><span class="o">.</span><span class="n">days</span>
<span class="k">while</span> <span class="n">days_left</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">event</span> <span class="o">=</span> <span class="n">gdata</span><span class="o">.</span><span class="n">calendar</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">CalendarEventEntry</span><span class="p">()</span>
<span class="k">if</span> <span class="n">days_left</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'</span><span class="si">%s</span><span class="s1"> Days Until Home for Christmas'</span> <span class="o">%</span> <span class="n">days_left</span>
<span class="k">elif</span> <span class="n">days_left</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'1 Day Until Home for Christmas'</span>
<span class="k">elif</span> <span class="n">days_left</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s1">'Going Home for Christmas'</span>
<span class="n">event</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="n">atom</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">Title</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="c1"># When</span>
<span class="n">start_time</span> <span class="o">=</span> <span class="s1">'2011-</span><span class="si">%02d</span><span class="s1">-</span><span class="si">%02d</span><span class="s1">T08:00:00.000-08:00'</span> <span class="o">%</span> <span class="p">(</span><span class="n">today</span><span class="o">.</span><span class="n">month</span><span class="p">,</span> <span class="n">today</span><span class="o">.</span><span class="n">day</span><span class="p">)</span>
<span class="n">end_time</span> <span class="o">=</span> <span class="s1">'2011-</span><span class="si">%02d</span><span class="s1">-</span><span class="si">%02d</span><span class="s1">T09:00:00.000-08:00'</span> <span class="o">%</span> <span class="p">(</span><span class="n">today</span><span class="o">.</span><span class="n">month</span><span class="p">,</span> <span class="n">today</span><span class="o">.</span><span class="n">day</span><span class="p">)</span>
<span class="n">event</span><span class="o">.</span><span class="n">when</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">gdata</span><span class="o">.</span><span class="n">calendar</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">When</span><span class="p">(</span>
<span class="n">start</span><span class="o">=</span><span class="n">start_time</span><span class="p">,</span>
<span class="n">end</span><span class="o">=</span><span class="n">end_time</span><span class="p">,</span>
<span class="n">reminder</span><span class="o">=</span><span class="p">[</span><span class="n">gdata</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">Reminder</span><span class="p">(</span><span class="n">hours</span><span class="o">=</span><span class="s1">'1'</span><span class="p">)]))</span>
<span class="n">gcal</span><span class="o">.</span><span class="n">InsertEvent</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
<span class="n">today</span> <span class="o">+=</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">days_left</span> <span class="o">-=</span> <span class="mi">1</span>
</code></pre></div>
<p>This script first authenticates by using the key/secret pair for the
application (retrieved from the settings page) and the key/secret pair
for the user token (that we obtained from the first script). To
authenticate, we explicitly construct an HMAC-SHA1 signed token in the
final auth state (3) of two-legged OAuth and then set the token on our
calendar client (<code>gcal</code>).</p>
<p>After authenticating, we start with today and figure out the number of
days in the countdown given my return date of December 23, 2011. With
these in hand, we can loop through until there are no days left,
creating a <code>CalendarEventEntry</code> with title as the number of days left
in the countdown and occurring from 8am to 9am PST (UTC -8). Notice also
I include a <code>gdata.data.Reminder</code> so I get an email at 7am every morning
(60 minutes before the event) updating my brain on the length of the
countdown!</p>
<h4>Cleanup:</h4>
<p>Be sure to go to your
<a href="https://accounts.google.com/IssuedAuthSubTokens">issued tokens page</a>
and revoke access to the App (e.g. <code>http://example.com</code>)
after doing this to avoid any unwanted security issues.</p>
<h4>References:</h4>
<p>I have never read this, but I'm sure the documentation on
<a href="http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html">Registration for Web-Based Applications</a>
is very helpful.</p>
<h4>Notes:</h4>
<ul>
<li>
<p>You can annoy other people by inviting them to these events for
them as well. To do so, simply add the following two lines before
inserting the event</p>
<div class="highlight"><pre><span></span><code><span class="n">who_add</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">gdata</span><span class="p">.</span><span class="n">calendar</span><span class="p">.</span><span class="k">data</span><span class="p">.</span><span class="n">EventWho</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s1">'name@mail.com'</span><span class="p">)</span><span class="n">event</span><span class="p">.</span><span class="n">who</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">who_add</span><span class="p">)</span><span class="w"></span>
</code></pre></div>
</li>
<li>
<p>Sometimes inserting an item results in a RedirectError, so it may
be safer to try the insert multiple times with a helper function
such as the following:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">try_insert</span><span class="p">(</span><span class="n">attempts</span><span class="p">,</span> <span class="n">gcal</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span>
<span class="kn">from</span> <span class="nn">gdata.client</span> <span class="kn">import</span> <span class="n">RedirectError</span>
<span class="k">while</span> <span class="n">attempts</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">gcal</span><span class="o">.</span><span class="n">InsertEvent</span><span class="p">(</span><span class="n">event</span><span class="p">)</span>
<span class="k">break</span>
<span class="k">except</span> <span class="n">RedirectError</span><span class="p">:</span>
<span class="n">attempts</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="k">if</span> <span class="n">attempts</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="nb">print</span> <span class="s1">'Insert "</span><span class="si">%s</span><span class="s1">" failed'</span> <span class="o">%</span> <span class="n">event</span><span class="o">.</span><span class="n">title</span><span class="o">.</span><span class="n">text</span>
</code></pre></div>
</li>
<li>
<p>In what I swear was a complete coincidence, v3 of the Calendar API was
<a href="http://googleappsdeveloper.blogspot.com/2011/11/introducing-next-version-of-google.html">announced</a>
today. I will try to use the
<a href="https://code.google.com/apis/calendar/v3/getting_started.html">new documentation</a>
to redo this quick and dirty example with v3.</p>
</li>
</ul>This Lobster, not so Bossy2011-10-17T00:00:00-07:002011-10-17T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-10-17:/2011/10/this-lobster-not-so-bossy.html<div style="text-align: center;">
<p><img alt="Baby Lobster" src="/images/baby_lobster.jpg"></p>
</div>Protecting Sensitive Information in Public Git Repositories2011-10-05T00:00:00-07:002011-10-05T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-10-05:/2011/10/protecting.html<p>On the (much too early) bus to work this morning, I was reading my
Twitter feed and saw an
<a href="https://twitter.com/#!/robhawkes/status/121593545202216960">interesting question</a>
from <a href="https://twitter.com/#!/robhawkes">Rob Hawkes</a>:</p>
<blockquote class="twitter-tweet tw-align-center" lang="en"><p>How do you handle config files in your apps when you use Git? I keep accidentally adding config files with sensitive data to Git. :(</p>— Robin Hawkes …</blockquote><p>On the (much too early) bus to work this morning, I was reading my
Twitter feed and saw an
<a href="https://twitter.com/#!/robhawkes/status/121593545202216960">interesting question</a>
from <a href="https://twitter.com/#!/robhawkes">Rob Hawkes</a>:</p>
<blockquote class="twitter-tweet tw-align-center" lang="en"><p>How do you handle config files in your apps when you use Git? I keep accidentally adding config files with sensitive data to Git. :(</p>— Robin Hawkes (@robhawkes) <a href="https://twitter.com/robhawkes/status/121593545202216960">October 5, 2011</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Rob's Twitter followers made all kinds of recommendations and Rob
eventually decided it was a solved problem, declaring</p>
<blockquote>
<p>Best method I've found so far is creating a temporary config file and
keeping that in <code>git</code>, then <code>.gitignore</code>ing the real one.</p>
</blockquote>
<p>and then</p>
<blockquote>
<p>Thanks for the config file tips! In the end I went with a <code>config.example.js</code>
file stored in <a href="http://git-scm.com/"><code>git</code></a> and a <code>config.js</code> file that is
ignored.</p>
</blockquote>
<p>For those following along at home, they mean the same thing.</p>
<p>As Rob was probably intending, this can be used for deploying an app on
your personal server, or for a sample App on a PaaS like
<a href="http://code.google.com/appengine/">Google App Engine</a> or
<a href="http://www.heroku.com/">Heroku</a>. When testing such an app, the ability
to have a native environment locally is a huge convenience, but the
overhead of remembering which private keys need to be hidden is a
headache and sometimes completely neglected. But it shouldn't be,
because <code>git</code> never forgets!</p>
<p>Anyone who has used <code>git</code> for any substantial amount of time probably
initially conceived of this hack when on first thought. (This is no
insult to Rob, just the inevitability of the pattern.) But, by the time
Rob posted his solution, I had moved on from this and came up a solution
that I think does the trick a bit more thoroughly. I envisioned a
solution which assumes people who checkout my code will want to keep
their config in a specified path that is already in the repo; of course,
I also wanted to share this with the interwebs.</p>
<p>Anyhow, this is quick and dirty. First, create <code>config.js</code> and <code>_config.js</code>
in the root directory of your git repository (the same directory that <code>.git/</code>
lives in). I intend <code>config.js</code> to be the local copy with my actual passwords
and keys and <code>_config.js</code> to hold the master contents that actually show up in
the public repo. For example, the contents of <code>config.js</code> are:</p>
<div class="highlight"><pre><span></span><code><span class="kd">var</span> <span class="nx">SECRET</span> <span class="o">=</span> <span class="s1">'Nnkrndkmn978489MDkjw'</span><span class="p">;</span>
</code></pre></div>
<p>and the contents of <code>_config.js</code>
are:</p>
<div class="highlight"><pre><span></span><code><span class="kd">var</span> <span class="nx">SECRET</span> <span class="o">=</span> <span class="s1">'SECRET'</span><span class="p">;</span>
</code></pre></div>
<p>Since I <strong>don't</strong> want a duplicate in my repo, I put a rule in my <code>.gitignore</code>
<a href="http://progit.org/book/ch2-2.html#ignoring_files">file</a> to ignore <code>_config.js</code>.
(For those unfamiliar, this can be done just by including <code>_config.js</code> on its
own line in the <code>.gitignore</code> file.) After doing so, I set up two
<a href="http://progit.org/book/ch7-3.html">git hooks</a>, a pre-commit and post-commit
hook.</p>
<p>To <strong>install</strong> the hooks, just add the files <code>pre-commit</code> and <code>post-commit</code>
to the <code>.git/hooks/</code> subdirectory in your repo.They are nearly identical files,
with a one-line difference. Both files simply swap the contents of <code>config.js</code>
and <code>_config.js</code>, while <code>pre-commit</code> also adds <code>config.js</code> to the changelist.
First I'll give you the contents of <code>pre-commit</code>, and then explain why it's
cool/safe:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="n">hooks_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="vm">__file__</span><span class="p">))</span>
<span class="n">relative_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">hooks_dir</span><span class="p">,</span> <span class="s1">'../..'</span><span class="p">)</span>
<span class="n">project_root</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">relative_dir</span><span class="p">)</span>
<span class="n">git_included_config</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">project_root</span><span class="p">,</span> <span class="s1">'config.js'</span><span class="p">)</span>
<span class="n">confidential_config</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">project_root</span><span class="p">,</span> <span class="s1">'_config.js'</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">git_included_config</span><span class="p">,</span> <span class="s1">'rU'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">git_included_contents</span> <span class="o">=</span> <span class="n">fh</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">confidential_config</span><span class="p">,</span> <span class="s1">'rU'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">confidential_contents</span> <span class="o">=</span> <span class="n">fh</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">git_included_config</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">confidential_contents</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">confidential_config</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">git_included_contents</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">'git add </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">git_included_config</span><span class="p">)</span>
</code></pre></div>
<p>Also note the contents of <code>post-commit</code> are exactly the same, except without
the final statement:</p>
<div class="highlight"><pre><span></span><code><span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">'git add </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">git_included_config</span><span class="p">)</span><span class="o">.</span>
</code></pre></div>
<p>So what is happening in this file:</p>
<ol>
<li>Uses the Python <code>os</code> module to determine the absolute path to the root
directory in your project by using the absolute path of the hook file,
backing up two directories and again find that absolute path.</li>
<li>Determines the two files which need to swap contents</li>
<li>Loads the contents into string variables and then writes them to the
opposite files</li>
<li>(only in <code>pre-commit</code>) Adds the included file to the changelist before
the commit occurs.</li>
</ol>
<p>Step 4 is actually the secret sauce. It puts cleaned, non-sensitive data
into the checked in <code>config.js</code> file and then updates the changelist before
making a commit, to ensure only the non-sensitive data goes in. Though you
could do this yourself by making an initial commit with clean data and then
never <code>git add</code>ing the file with your actual data, these hooks prevent an
accident and allow you to update your local <code>_config.js</code> file with more
fields as your config spec changes.</p>
<p>But wait bossylobster, you say, what if one of the hooks doesn't occur?
You are right! As <code>pre-commit</code> stands above, if the changelist is empty we
have problems. Since the pre-commit hook changes <code>config.js</code> to the same
value in <code>HEAD</code>, <code>git</code> will tell us either <strong>nothing to commit</strong> or
<strong>no changes added to commit</strong>. In this case, the commit will exit and the
post-commit hook will never occur. <strong>THIS IS VERY BAD</strong>, since the contents of
<code>config.js</code> and <code>_config.js</code> will be switched but not switched back. So, to
account for this, we need to append the following code to the end of
<code>pre-commit</code>:</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="n">os</span><span class="o">.</span><span class="n">popen</span><span class="p">(</span><span class="s1">'git st'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">git_status</span> <span class="o">=</span> <span class="n">fh</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">if</span> <span class="p">(</span><span class="s1">'nothing to commit'</span> <span class="ow">in</span> <span class="n">git_status</span> <span class="ow">or</span>
<span class="s1">'no changes added to commit'</span> <span class="ow">in</span> <span class="n">git_status</span> <span class="ow">or</span>
<span class="s1">'nothing added to commit'</span> <span class="ow">in</span> <span class="n">git_status</span><span class="p">):</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'# From pre-commit hook: No commit necessary, '</span>
<span class="s1">'sensitive config unchanged. #'</span><span class="p">)</span>
<span class="n">hash_head</span> <span class="o">=</span> <span class="s1">'#'</span> <span class="o">*</span> <span class="nb">len</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="nb">print</span> <span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="se">\n</span><span class="si">%s</span><span class="se">\n</span><span class="si">%s</span><span class="se">\n\n</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">hash_head</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">hash_head</span><span class="p">)),</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">git_included_config</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">git_included_contents</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">confidential_config</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">fh</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">confidential_contents</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<p>For final versions see the
<a href="https://gist.github.com/dhermes/21b152c25a321b554b61">pre-commit</a> and
<a href="https://gist.github.com/dhermes/877ed7c9838d6fc5bb08">post-commit</a>
files. Thanks again to <a href="https://twitter.com/#!/robhawkes">Rob Hawkes</a>
for the idea/work break over lunch!</p>
<h4>Update 1:</h4>
<p>One of Rob's followers, <a href="https://twitter.com/#!/nrocy">Paul King</a>, found and
<a href="https://twitter.com/#!/nrocy/status/124468167086051328">tweeted</a> a very
different alternative that is also pretty cool. Check out the
<a href="http://archive.robwilkerson.org/2010/03/02/git-tip-ignore-changes-to-tracked-files/">post</a>
he found by <a href="https://twitter.com/#!/robwilkerson">Rob Wilkerson</a>.</p>
<h4>Update 2:</h4>
<p>I swapped out a screen shot of the tweet for a CSS-ified
version, inspired by and based on a design used on Mashable.</p>
<h4>Update 3:</h4>
<p>Some change in <code>git</code> causes empty commits to be allowed. I either didn't
notice this before or it just showed up in <code>git</code>. So I added <code>sys.exit(1)</code>
to force the pre-commit script to fail when nothing is changed and added
a check for the phrase <strong>nothing added to commit</strong> as well.</p>Finding (Fibonacci) Golden Nuggets Part 22011-08-29T00:00:00-07:002011-08-29T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-08-29:/2011/08/finding-fibonacci-golden-nuggets-part-2.html<p>This is the <strong>mostly code</strong> second half of a
<a href="/2011/08/finding-fibonacci-golden-nuggets.html">two part post</a>
that delivers on a promise of meaningful uses of some theory I
overviewed in my last set of posts.If you see words like topograph,
river, and base and you aren't sure what I mean, you may want …</p><p>This is the <strong>mostly code</strong> second half of a
<a href="/2011/08/finding-fibonacci-golden-nuggets.html">two part post</a>
that delivers on a promise of meaningful uses of some theory I
overviewed in my last set of posts.If you see words like topograph,
river, and base and you aren't sure what I mean, you may want to read
that last
<a href="/2011/08/conways-topograph-part-3.html">set of posts</a>.</p>
<p>In the first half of this post, I outlined a solution to Project Euler
<a href="http://projecteuler.net/index.php?section=problems&id=137">problem 137</a>
and will continue with the solution here. Stop reading now if you don't want to
be spoiled. There was no code in the first post, so this post will be
mostly code, providing a pretty useful abstraction for dealing with
binary quadratic forms.</p>
<p>In the very specific solution, I was able to use one picture to completely
classify all integer solutions to the equation
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><msup><mi>y</mi><mn>2</mn></msup><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">5 x^2 - y^2 = 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.008548em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span> due to some dumb luck. In the solution, we
were able to use</p>
<blockquote>
<p>Since every edge protruding from the river on the positive side has a
value of 4 on a side...by the climbing lemma, we know all values above
those on the river have value greater than 4</p>
</blockquote>
<p>but this is no help when trying to find solutions to
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><msup><mi>y</mi><mn>2</mn></msup><mo>=</mo><mn>9</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">5 x^2 - y^2 = 9,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.008548em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">9</span><span class="mpunct">,</span></span></span></span> for example.</p>
<p>To answer the question <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><msup><mi>y</mi><mn>2</mn></msup><mo>=</mo><mn>9</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">5 x^2 - y^2 = 9,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.008548em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">9</span><span class="mpunct">,</span></span></span></span> we'll use the same
pretty picture, but emphasize different parts of it. As you can see
below, to classify all the values, we only need to travel from the
initial base</p>
<div style="text-align: center;">
<p><img alt="Golden Nugget First Base" src="/images/golden_nugget_first_base.png"></p>
</div>
<p>along the river until we arrive at an identical base as the blue circles
indicate below:</p>
<div style="text-align: center;">
<p><img alt="Golden Nugget Next" src="/images/golden_nugget_next.png"></p>
</div>
<p>As noted above,for problem 137, we luckily were concerned about finding
values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn></mrow><annotation encoding="application/x-tex">4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span> or <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span></span></span></span> and the climbing lemma
saved us from leaving the river. However, as I've noted above with
<span class="Apple-style-span" style="color: #6fa8dc;">#1</span>,
<span class="Apple-style-span" style="color: #6fa8dc;">#2</span>,
<span class="Apple-style-span" style="color: #6fa8dc;">#3</span>, and
<span class="Apple-style-span" style="color: #6fa8dc;">#4</span>, there
are four <strong>tributaries</strong> coming from the river where we can consider larger
values. Using the <strong>Arithmetic Progression Rule</strong>, we find values
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>19</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">19,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">19</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>11</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">11,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">11</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>11</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">11,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">11</span><span class="mpunct">,</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>19</mn></mrow><annotation encoding="application/x-tex">19</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">19</span></span></span></span> as the first set of values above the river. From this
point, we can stop checking for solutions to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mn>9</mn></mrow><annotation encoding="application/x-tex">f(x, y) = 9</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">9</span></span></span></span>
since the climbing lemma says all further values above the tributaries will be
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>11</mn></mrow><annotation encoding="application/x-tex">11</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">11</span></span></span></span> or greater. Thus, the only solutions come via scaling
solutions of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">f(x, y) = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> by a factor of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn></mrow><annotation encoding="application/x-tex">3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span>
(using homogeneity of a quadratic form).</p>
<p>Now for the (Python) code.</p>
<p>First, the data structure will be representative of a base along the
river, but will also include the previous and next faces (on the shared
superbases) and so we'll call it a <strong>juncture</strong> (my term, not Conway's).
Each face in a juncture needs to be represented by both the pair
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span> and the value that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> takes on this
face. For our sanity, we organize a juncture as a tuple
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>B</mi><mo separator="true">,</mo><mi>P</mi><mo separator="true">,</mo><mi>N</mi><mo separator="true">,</mo><mi>F</mi><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">(B, P, N, F),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> (in that order)</p>
<div style="text-align: center;">
<p><img alt="Golden Nugget Juncture" src="/images/juncture.png"></p>
</div>
<p>where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> form a base straddling the
river, with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> taking the positive value and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> negative, as well as <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi></mrow><annotation encoding="application/x-tex">B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> the face "back"
according to our orientation and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi></mrow><annotation encoding="application/x-tex">F</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span></span></span></span> the face "forward". Note,
depending on the value of the form at <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">F,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mpunct">,</span></span></span></span> the river may
"turn left" or "turn right" at the superbase formed by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">P,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi></mrow><annotation encoding="application/x-tex">F</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span></span></span></span>.</p>
<p>To move "along the river until we arrive at an identical base", we need
a way to move "forward" (according to our imposed orientation) to the
next juncture on the river. Moving along the river, we'll often come to
superbases <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>B</mi><mo separator="true">,</mo><mi>N</mi><mo separator="true">,</mo><mi>P</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(B, N, P)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)</span></span></span></span> and need to calculate the forward face
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi></mrow><annotation encoding="application/x-tex">F</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span></span></span></span>. To calculate <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">F,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mpunct">,</span></span></span></span> assume we have
<a href="https://github.com/dhermes/project-euler/blob/31b005fe346927bc64e30f63381c7f675533752a/python/conway_topograph.py#L33">already written</a>
a <code>plus</code>
function that determines the vector at <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi></mrow><annotation encoding="application/x-tex">F</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span></span></span></span>
by adding the vectors from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>N</mi></mrow><annotation encoding="application/x-tex">N</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span></span></span></span> and
determines the value at <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>F</mi></mrow><annotation encoding="application/x-tex">F</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span></span></span></span> by using the arithmetic
progression rule with the values at all three faces in the superbase.
Using this helper function, we can define a way to get the next juncture
by turning left or right:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">next_juncture_on_river</span><span class="p">(</span><span class="n">juncture</span><span class="p">):</span>
<span class="n">B</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">F</span> <span class="o">=</span> <span class="n">juncture</span>
<span class="n">forward_val</span> <span class="o">=</span> <span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="n">forward_val</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># turn left</span>
<span class="n">NEXT</span> <span class="o">=</span> <span class="n">plus</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">return</span> <span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">NEXT</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">forward_val</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># turn right</span>
<span class="n">NEXT</span> <span class="o">=</span> <span class="n">plus</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">P</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">return</span> <span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">NEXT</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'No infinite river here.'</span><span class="p">)</span>
</code></pre></div>
<p>Next, to know when to stop crawling on the river, we need to know when
we have returned to an identical juncture, so we define:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">juncture_ident</span><span class="p">(</span><span class="n">juncture1</span><span class="p">,</span> <span class="n">juncture2</span><span class="p">):</span>
<span class="n">B1</span><span class="p">,</span> <span class="n">P1</span><span class="p">,</span> <span class="n">N1</span><span class="p">,</span> <span class="n">F1</span> <span class="o">=</span> <span class="n">juncture1</span>
<span class="n">B2</span><span class="p">,</span> <span class="n">P2</span><span class="p">,</span> <span class="n">N2</span><span class="p">,</span> <span class="n">F2</span> <span class="o">=</span> <span class="n">juncture2</span>
<span class="k">return</span> <span class="p">((</span><span class="n">B1</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">B2</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="ow">and</span> <span class="p">(</span><span class="n">P1</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">P2</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="ow">and</span>
<span class="p">(</span><span class="n">N1</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">N2</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="ow">and</span> <span class="p">(</span><span class="n">F1</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">F2</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
</code></pre></div>
<p>Using these functions, we can first find the recurrence that will take
us from a base of solutions to all solutions and second, keep track of
the positive faces on the river to generalize the solution of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mi>z</mi></mrow><annotation encoding="application/x-tex">f(x, y) = z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span></span>. For both of these problems, we impose a
simplification for the sake of illustration. We will only be considering
quadratic forms</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mi>a</mi><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mi>b</mi><msup><mi>y</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">f(x, y) = a x^2 + b y^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0585479999999998em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">b</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>></mo><mn>0</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">a > 0,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo><</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">b < 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mrow><mo fence="true">∣</mo><mfrac><mi>a</mi><mi>b</mi></mfrac><mo fence="true">∣</mo></mrow></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{\left|\frac{a}{b}\right|}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.84em;vertical-align:-0.5990099999999998em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2409900000000003em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.86199em;"><span style="top:-2.2559899999999997em;"><span class="pstrut" style="height:2.606em;"></span><span class="delimsizinginner delim-size1"><span>∣</span></span></span><span style="top:-2.85399em;"><span class="pstrut" style="height:2.606em;"></span><span style="height:0.016em;width:0.333em;"><svg xmlns="http://www.w3.org/2000/svg" width='0.333em' height='0.016em' style='width:0.333em' viewBox='0 0 333 16' preserveAspectRatio='xMinYMin'><path d='M145 0 H188 V16 H145z M145 0 H188 V16 H145z'/></svg></span></span><span style="top:-2.86199em;"><span class="pstrut" style="height:2.606em;"></span><span class="delimsizinginner delim-size1"><span>∣</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.35000999999999993em;"><span></span></span></span></span></span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">b</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">a</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.86199em;"><span style="top:-2.2559899999999997em;"><span class="pstrut" style="height:2.606em;"></span><span class="delimsizinginner delim-size1"><span>∣</span></span></span><span style="top:-2.85399em;"><span class="pstrut" style="height:2.606em;"></span><span style="height:0.016em;width:0.333em;"><svg xmlns="http://www.w3.org/2000/svg" width='0.333em' height='0.016em' style='width:0.333em' viewBox='0 0 333 16' preserveAspectRatio='xMinYMin'><path d='M145 0 H188 V16 H145z M145 0 H188 V16 H145z'/></svg></span></span><span style="top:-2.86199em;"><span class="pstrut" style="height:2.606em;"></span><span class="delimsizinginner delim-size1"><span>∣</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.35000999999999993em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.20099em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90
l0 -0
c4,-6.7,10,-10,18,-10 H400000v40
H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7
s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744
c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30
c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722
c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5
c53.7,-170.3,84.5,-266.8,92.5,-289.5z
M1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5990099999999998em;"><span></span></span></span></span></span></span></span></span> is not rational. This
guarantees the existence of a river. We will pass such forms as an
argument <code>form=(a, b)</code>
to our functions. We start our river at the juncture defined by the trivial base
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo><mo separator="true">,</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1, 0), (0, 1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span></p>
<div style="text-align: center;">
<p><img alt="Golden Nugget Trivial Base" src="/images/trivial_base.png"></p>
</div>
<p>and crawl the river using the functions defined above.</p>
<blockquote>
<p><strong>NOTE</strong>: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo>=</mo><mi>a</mi><mo stretchy="false">(</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mi>b</mi><mo stretchy="false">(</mo><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f(1, -1) = a(1)^2 + b(-1)^2 = a + b,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">−</span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal">a</span><span class="mopen">(</span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mopen">(</span><span class="mord">−</span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">b</span><span class="mpunct">,</span></span></span></span> etc.</p>
</blockquote>
<p>To find the recurrence, we need just walk along the river until we get
an identical juncture where the trivial base is replaced by the base
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>p</mi><mo separator="true">,</mo><mi>q</mi><mo stretchy="false">)</mo><mo separator="true">,</mo><mo stretchy="false">(</mo><mi>r</mi><mo separator="true">,</mo><mi>s</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(p, q), (r, s)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">s</span><span class="mclose">)</span></span></span></span>. Using the same terminology as in
<a href="/2011/08/finding-fibonacci-golden-nuggets.html">part one</a>,
let the base vectors define a sequence
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mrow><mo fence="true">{</mo><mo stretchy="false">(</mo><msub><mi>u</mi><mi>k</mi></msub><mo separator="true">,</mo><msub><mi>v</mi><mi>k</mi></msub><mo stretchy="false">)</mo><mo fence="true">}</mo></mrow><mrow><mi>k</mi><mo>≥</mo><mn>0</mn></mrow></msub></mrow><annotation encoding="application/x-tex">\left\{(u_k, v_k)\right\}_{k \geq 0}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.144879em;vertical-align:-0.394879em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1864079999999999em;"><span style="top:-2.4003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mrel mtight">≥</span><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.394879em;"><span></span></span></span></span></span></span></span></span></span> with
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">u_0 = (1, 0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>v</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">v_0 = (0, 1),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> then we
have a recurrence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>p</mi><msub><mi>u</mi><mi>k</mi></msub><mo>+</mo><mi>q</mi><msub><mi>v</mi><mi>k</mi></msub></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>v</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>r</mi><msub><mi>u</mi><mi>k</mi></msub><mo>+</mo><mi>s</mi><msub><mi>v</mi><mi>k</mi></msub><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}u_{k + 1} &= p u_k + q v_k \\ v_{k + 1} &= r u_k + s v_k. \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.0000000000000004em;vertical-align:-1.2500000000000002em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">p</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">s</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Using this</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>2</mn></mrow></msub><mo>−</mo><mi>p</mi><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mi>s</mi><mo stretchy="false">(</mo><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mi>p</mi><msub><mi>u</mi><mi>k</mi></msub><mo stretchy="false">)</mo><mo>=</mo><mi>q</mi><msub><mi>v</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mi>s</mi><mo stretchy="false">(</mo><mi>q</mi><msub><mi>v</mi><mi>k</mi></msub><mo stretchy="false">)</mo><mo>=</mo><mi>q</mi><mo stretchy="false">(</mo><mi>r</mi><msub><mi>u</mi><mi>k</mi></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">u_{k + 2} - p u_{k + 1} - s(u_{k + 1} - p u_k) = q v_{k + 1} - s (q v_k) = q(r u_k)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.791661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.791661em;vertical-align:-0.208331em;"></span><span class="mord mathnormal">p</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">s</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.791661em;vertical-align:-0.208331em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">s</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span>
</blockquote></div>
<p>hence <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi></mrow><annotation encoding="application/x-tex">u</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">u</span></span></span></span> satisfies the recurrence
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>2</mn></mrow></msub><mo>=</mo><mo stretchy="false">(</mo><mi>r</mi><mi>q</mi><mo>−</mo><mi>p</mi><mi>s</mi><mo stretchy="false">)</mo><msub><mi>u</mi><mi>k</mi></msub><mo>+</mo><mo stretchy="false">(</mo><mi>p</mi><mo>+</mo><mi>s</mi><mo stretchy="false">)</mo><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">u_{k + 2} = (r q - p s)u_k + (p + s)u_{k + 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">p</span><span class="mord mathnormal">s</span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">s</span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span>. (You
can check that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi></mrow><annotation encoding="application/x-tex">v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span> satisfies this as well.) Hence our function
to spit out the recurrence coefficients is:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">get_recurrence</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
<span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">form</span>
<span class="n">B</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">),</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">)</span>
<span class="n">P</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">a</span><span class="p">)</span>
<span class="n">N</span> <span class="o">=</span> <span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">b</span><span class="p">)</span>
<span class="n">F</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">)</span>
<span class="n">J_init</span> <span class="o">=</span> <span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
<span class="n">J_curr</span> <span class="o">=</span> <span class="n">next_juncture_on_river</span><span class="p">(</span><span class="n">J_init</span><span class="p">)</span>
<span class="k">while</span> <span class="ow">not</span> <span class="n">juncture_ident</span><span class="p">(</span><span class="n">J_init</span><span class="p">,</span> <span class="n">J_curr</span><span class="p">):</span>
<span class="n">J_curr</span> <span class="o">=</span> <span class="n">next_juncture_on_river</span><span class="p">(</span><span class="n">J_curr</span><span class="p">)</span>
<span class="n">final_B</span><span class="p">,</span> <span class="n">final_P</span><span class="p">,</span> <span class="n">final_N</span><span class="p">,</span> <span class="n">final_F</span> <span class="o">=</span> <span class="n">J_curr</span>
<span class="n">p</span><span class="p">,</span> <span class="n">q</span> <span class="o">=</span> <span class="n">final_P</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">r</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="n">final_N</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">return</span> <span class="p">(</span><span class="n">r</span><span class="o">*</span><span class="n">q</span> <span class="o">-</span> <span class="n">p</span><span class="o">*</span><span class="n">s</span><span class="p">,</span> <span class="n">p</span> <span class="o">+</span> <span class="n">s</span><span class="p">)</span>
</code></pre></div>
<p>For solving <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mi>z</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f(x, y) = z,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>z</mi><mo>></mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(z > 0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span>
we need to consider all the positive tributaries coming out of the river and
let them grow and grow until the climbing lemma tells us we no longer need
to consider values larger than <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>z</mi></mrow><annotation encoding="application/x-tex">z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span></span>. In order to consider
tributaries, we describe a new kind of juncture. Instead of having a
positive/negative base in the center of the juncture, we have two consecutive
faces from the positive side</p>
<div style="text-align: center;">
<p><img alt="Golden Nugget Positive Root" src="/images/positive_root.png"></p>
</div>
<p>and have the negative from across the river as the "back" face. With
this definition, we first write a function to return all tributaries:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">all_positive_tributaries</span><span class="p">(</span><span class="n">form</span><span class="p">):</span>
<span class="c1"># ...Initialization logic...</span>
<span class="n">new_positives</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">J_curr</span> <span class="o">=</span> <span class="n">next_juncture_on_river</span><span class="p">(</span><span class="n">J_init</span><span class="p">)</span>
<span class="k">while</span> <span class="ow">not</span> <span class="n">juncture_ident</span><span class="p">(</span><span class="n">J_init</span><span class="p">,</span> <span class="n">J_curr</span><span class="p">):</span>
<span class="c1"># we add a new positive if the forward</span>
<span class="c1"># value is positive</span>
<span class="n">forward</span> <span class="o">=</span> <span class="n">J_curr</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="n">forward</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="n">new_positives</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">J_curr</span><span class="p">)</span>
<span class="n">J_curr</span> <span class="o">=</span> <span class="n">next_juncture_on_river</span><span class="p">(</span><span class="n">J_curr</span><span class="p">)</span>
<span class="c1"># For each (B, P, N, F) in new_positives, we want to</span>
<span class="c1"># transform to a juncture with positive values, which will</span>
<span class="c1"># be (N, P_1, P_2, P_F)</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">new_positive</span> <span class="ow">in</span> <span class="n">new_positives</span><span class="p">:</span>
<span class="n">B</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">F</span> <span class="o">=</span> <span class="n">new_positive</span>
<span class="n">new_face</span> <span class="o">=</span> <span class="n">plus</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">tributary</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">new_face</span><span class="p">)</span>
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tributary</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
</code></pre></div>
<p>For each tributary, we can climb up away from the river until our values
are too large. So we write a helper function to take a given tributary
and a max value and recursively "climb" the topograph until we exceed
the value. This function will naively return all possible faces (value
and vector) without checking the actual values.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">seek_up_to_val</span><span class="p">(</span><span class="n">juncture</span><span class="p">,</span> <span class="n">max_value</span><span class="p">):</span>
<span class="n">N</span><span class="p">,</span> <span class="n">P_1</span><span class="p">,</span> <span class="n">P_2</span><span class="p">,</span> <span class="n">P_F</span> <span class="o">=</span> <span class="n">juncture</span>
<span class="k">if</span> <span class="n">P_F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">></span> <span class="n">max_value</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">[</span><span class="n">P_F</span><span class="p">]</span>
<span class="n">turn_left</span> <span class="o">=</span> <span class="n">plus</span><span class="p">(</span><span class="n">P_1</span><span class="p">,</span> <span class="n">P_F</span><span class="p">,</span> <span class="n">P_2</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">J_left</span> <span class="o">=</span> <span class="p">(</span><span class="n">P_2</span><span class="p">,</span> <span class="n">P_F</span><span class="p">,</span> <span class="n">P_1</span><span class="p">,</span> <span class="n">turn_left</span><span class="p">)</span>
<span class="n">result</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">seek_up_to_val</span><span class="p">(</span><span class="n">J_left</span><span class="p">,</span> <span class="n">max_value</span><span class="p">))</span>
<span class="n">turn_right</span> <span class="o">=</span> <span class="n">plus</span><span class="p">(</span><span class="n">P_2</span><span class="p">,</span> <span class="n">P_F</span><span class="p">,</span> <span class="n">P_1</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">J_right</span> <span class="o">=</span> <span class="p">(</span><span class="n">P_1</span><span class="p">,</span> <span class="n">P_F</span><span class="p">,</span> <span class="n">P_2</span><span class="p">,</span> <span class="n">turn_right</span><span class="p">)</span>
<span class="n">result</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">seek_up_to_val</span><span class="p">(</span><span class="n">J_right</span><span class="p">,</span> <span class="n">max_value</span><span class="p">))</span>
<span class="k">return</span> <span class="n">result</span>
</code></pre></div>
<p>Finally, we can combine these two helper functions into a function which
will find all solutions to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mi>z</mi></mrow><annotation encoding="application/x-tex">f(x, y) = z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span></span> above the river. We
may have a pair (or pairs) <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span> on the topograph where
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mi>z</mi><msup><mi>k</mi><mn>2</mn></msup></mfrac></mrow><annotation encoding="application/x-tex">f(x, y) = \frac{z}{k^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.040392em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.04398em;">z</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> for some integer
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span>; if so, this gives rise to a solution
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>k</mi><mi>x</mi><mo separator="true">,</mo><mi>k</mi><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(kx, ky)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span> which we'll be sure to account for in our function.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">all_values_on_form</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="c1"># Use a helper (factors) to get all positive integer factors of value</span>
<span class="n">factor_list</span> <span class="o">=</span> <span class="n">factors</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="c1"># Use another helper (is_square) to determine which factors can be</span>
<span class="c1"># written as value/k^2 for some integer k</span>
<span class="n">valid_factors</span> <span class="o">=</span> <span class="p">[</span><span class="n">factor</span> <span class="k">for</span> <span class="n">factor</span> <span class="ow">in</span> <span class="n">factor_list</span>
<span class="k">if</span> <span class="n">is_square</span><span class="p">(</span><span class="n">value</span><span class="o">/</span><span class="n">factor</span><span class="p">)]</span>
<span class="n">tributaries</span> <span class="o">=</span> <span class="n">all_positive_tributaries</span><span class="p">(</span><span class="n">form</span><span class="p">)</span>
<span class="n">found</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="k">for</span> <span class="n">tributary</span> <span class="ow">in</span> <span class="n">tributaries</span><span class="p">:</span>
<span class="n">candidates</span> <span class="o">=</span> <span class="n">seek_up_to_val</span><span class="p">(</span><span class="n">tributary</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="n">found</span><span class="o">.</span><span class="n">update</span><span class="p">([</span><span class="n">candidate</span> <span class="k">for</span> <span class="n">candidate</span> <span class="ow">in</span> <span class="n">candidates</span>
<span class="k">if</span> <span class="n">candidate</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="ow">in</span> <span class="n">valid_factors</span><span class="p">])</span>
<span class="c1"># Since each tributary is of the form (N, P_1, P_2, P_F) for</span>
<span class="c1"># P_1, P_2 on the river, we need only consider P_1 and P_2 since</span>
<span class="c1"># those faces above are in candidates. But P_2 will always be in</span>
<span class="c1"># next tributary, so we need not count it. You may assume this ignores</span>
<span class="c1"># the very final tributary, but here P_2 actually lies in the</span>
<span class="c1"># second period of the river</span>
<span class="n">N</span><span class="p">,</span> <span class="n">P_1</span><span class="p">,</span> <span class="n">P_2</span><span class="p">,</span> <span class="n">F</span> <span class="o">=</span> <span class="n">tributary</span>
<span class="k">if</span> <span class="n">P_1</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="ow">in</span> <span class="n">valid_factors</span><span class="p">:</span>
<span class="n">found</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">P_1</span><span class="p">)</span>
<span class="c1"># Finally we must scale up factors to account for</span>
<span class="c1"># the reduction by a square multiple</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">face</span> <span class="ow">in</span> <span class="n">found</span><span class="p">:</span>
<span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">),</span> <span class="n">val</span> <span class="o">=</span> <span class="n">face</span>
<span class="k">if</span> <span class="n">val</span> <span class="o"><</span> <span class="n">value</span><span class="p">:</span>
<span class="n">ratio</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sqrt</span><span class="p">(</span><span class="n">value</span><span class="o">/</span><span class="n">val</span><span class="p">))</span>
<span class="n">x</span> <span class="o">*=</span> <span class="n">ratio</span>
<span class="n">y</span> <span class="o">*=</span> <span class="n">ratio</span>
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>
<span class="k">return</span> <span class="n">result</span>
</code></pre></div>
<p>Combining <code>all_values_on_form</code>
with <code>get_recurrence</code>,
we can parameterize every existing solution!</p>
<p>As far as Project Euler is concerned, in addition to Problem 137, I was
able to write lightning fast solutions to
<a href="http://projecteuler.net/index.php?section=problems&id=66">Problem 66</a>,
<a href="http://projecteuler.net/index.php?section=problems&id=94">Problem 94</a>,
<a href="http://projecteuler.net/index.php?section=problems&id=100">Problem 100</a>,
<a href="http://projecteuler.net/index.php?section=problems&id=138">Problem 138</a>
and <a href="http://projecteuler.net/index.php?section=problems&id=140">Problem140</a>
using tools based on the above — a general purpose library for solving
binary quadratic forms over integers!</p>Finding (Fibonacci) Golden Nuggets Part 12011-08-28T00:00:00-07:002011-08-28T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-08-28:/2011/08/finding-fibonacci-golden-nuggets.html<p>As I mentioned in my last set ofposts, the content would go somewhere
and this post will be the first to deliver on that. In fact this is the
<strong>all math, no code</strong> first half of a two part post that will deliver. If
you see words like topograph, river …</p><p>As I mentioned in my last set ofposts, the content would go somewhere
and this post will be the first to deliver on that. In fact this is the
<strong>all math, no code</strong> first half of a two part post that will deliver. If
you see words like topograph, river, and base and you aren't sure what I
mean, you may want to read that last
<a href="/2011/08/conways-topograph-part-3.html">set of posts</a>.</p>
<p>In this post, I outline a solution to Project Euler
<a href="http://projecteuler.net/index.php?section=problems&id=137">problem 137</a>, so
stop reading now if you don't want to be spoiled. There is no code here, but
the <a href="/2011/08/finding-fibonacci-golden-nuggets-part-2.html">second half</a>
of this post has a pretty useful abstraction.</p>
<p>The problems asks us to consider</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mi>F</mi></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo><mo>=</mo><mi>z</mi><msub><mi>F</mi><mn>1</mn></msub><mo>+</mo><msup><mi>z</mi><mn>2</mn></msup><msub><mi>F</mi><mn>2</mn></msub><mo>+</mo><msup><mi>z</mi><mn>3</mn></msup><msub><mi>F</mi><mn>3</mn></msub><mo>+</mo><mo>…</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">A_F(z) = z F_1 + z^2 F_2 + z^3 F_3 + \ldots,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0141079999999998em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0141079999999998em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.31744em;vertical-align:-0.19444em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span></span></span></span></span>
</blockquote></div>
<p>the generating polynomial for the <a href="#footnote">Fibonacci sequence</a>
The problem defines (without stating so), a sequence
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mrow><mo fence="true">{</mo><msub><mi>z</mi><mi>n</mi></msub><mo fence="true">}</mo></mrow><mrow><mi>n</mi><mo>></mo><mn>0</mn></mrow></msub></mrow><annotation encoding="application/x-tex">\left\{z_n\right\}_{n > 0}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.07707em;vertical-align:-0.32706999999999997em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151408em;"><span style="top:-2.4003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mrel mtight">></span><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.32706999999999997em;"><span></span></span></span></span></span></span></span></span></span> where
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>A</mi><mi>F</mi></msub><mo stretchy="false">(</mo><msub><mi>z</mi><mi>n</mi></msub><mo stretchy="false">)</mo><mo>=</mo><mi>n</mi></mrow><annotation encoding="application/x-tex">A_F(z_n) = n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> and asks us to find the values
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> for which <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>z</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">z_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is rational.
Such a value <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> is called a <strong>golden nugget</strong>. As noted in
the problem statement,
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><msub><mi>A</mi><mi>F</mi></msub><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mo fence="true">)</mo></mrow><mo>=</mo><mn>2</mn><mo separator="true">,</mo></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle A_F\left(\frac{1}{2}\right) = 2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">2</span><span class="mpunct">,</span></span></span></span>
hence <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><msub><mi>z</mi><mn>2</mn></msub><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle z_2 = \frac{1}{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.04398em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> is rational and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span> is the first golden nugget.</p>
<p>As a first step, we determine a criterion for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> to be a
golden nugget by analyzing the equation <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>A</mi><mi>F</mi></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo><mo>=</mo><mi>n</mi></mrow><annotation encoding="application/x-tex">A_F(z) = n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span>. With
the recurrence relation given by the Fibonacci sequence as inspiration, we
consider</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mo stretchy="false">(</mo><mi>z</mi><mo>+</mo><msup><mi>z</mi><mn>2</mn></msup><mo stretchy="false">)</mo><msub><mi>A</mi><mi>F</mi></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>z</mi><mn>2</mn></msup><msub><mi>F</mi><mn>1</mn></msub></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>+</mo><msup><mi>z</mi><mn>3</mn></msup><msub><mi>F</mi><mn>2</mn></msub><mo>+</mo><msup><mi>z</mi><mn>4</mn></msup><msub><mi>F</mi><mn>3</mn></msub><mo>+</mo><mo>…</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>+</mo><msup><mi>z</mi><mn>3</mn></msup><msub><mi>F</mi><mn>1</mn></msub><mo>+</mo><msup><mi>z</mi><mn>4</mn></msup><msub><mi>F</mi><mn>2</mn></msub><mo>+</mo><msup><mi>z</mi><mn>5</mn></msup><msub><mi>F</mi><mn>3</mn></msub><mo>+</mo><mo>…</mo><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}(z + z^2)A_F(z) = z^2 F_1 &+ z^3 F_2 + z^4 F_3 + \ldots\\ &+z^3 F_1 + z^4 F_2 + z^5 F_3 + \ldots. \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.048216em;vertical-align:-1.274108em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.774108em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.385892em;"><span class="pstrut" style="height:3em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.274108em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.774108em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner">…</span></span></span><span style="top:-2.385892em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.274108em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Due to the fact that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>F</mi><mn>2</mn></msub><mo>=</mo><msub><mi>F</mi><mn>1</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">F_2 = F_1 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and the nature
of the recurrence relation, we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mi>z</mi><mo>+</mo><msup><mi>z</mi><mn>2</mn></msup><mo stretchy="false">)</mo><msub><mi>A</mi><mi>F</mi></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>z</mi><mn>2</mn></msup><msub><mi>F</mi><mn>2</mn></msub><mo>+</mo><msup><mi>z</mi><mn>3</mn></msup><msub><mi>F</mi><mn>3</mn></msub><mo>+</mo><msup><mi>z</mi><mn>4</mn></msup><msub><mi>F</mi><mn>4</mn></msub><mo>+</mo><mo>…</mo><mo>=</mo><msub><mi>A</mi><mi>F</mi></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo><mo>−</mo><mi>z</mi></mrow><annotation encoding="application/x-tex">(z +z^2)A_F(z) = z^2 F_2 + z^3 F_3 + z^4 F_4 + \ldots = A_F(z) -z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.0141079999999998em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0141079999999998em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0141079999999998em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.36687em;vertical-align:0em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span></span></span>
</blockquote></div>
<p>which implies</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>A</mi><mi>F</mi></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mi>z</mi><mrow><mn>1</mn><mo>−</mo><mi>z</mi><mo>−</mo><msup><mi>z</mi><mn>2</mn></msup></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">A_F(z) = \frac{z}{1 - z -z^2}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.8768900000000002em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Now solving<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>A</mi><mi>F</mi></msub><mo stretchy="false">(</mo><mi>z</mi><mo stretchy="false">)</mo><mo>=</mo><mi>n</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">A_F(z) = n,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32833099999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">F</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">n</span><span class="mpunct">,</span></span></span></span> we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>z</mi><mo>=</mo><mi>n</mi><mo>−</mo><mi>n</mi><mi>z</mi><mo>−</mo><mi>n</mi><msup><mi>z</mi><mn>2</mn></msup><mo>⇒</mo><mi>n</mi><msup><mi>z</mi><mn>2</mn></msup><mo>+</mo><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mi>z</mi><mo>−</mo><mi>n</mi><mo>=</mo><mn>0.</mn></mrow><annotation encoding="application/x-tex">z = n - n z - n z^2 \Rightarrow n z^2 + (n + 1)z - n = 0.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8641079999999999em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">n</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0.</span></span></span></span></span>
</blockquote></div>
<p>In order for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> to be a golden nugget, we must have the
solutions <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>z</mi></mrow><annotation encoding="application/x-tex">z</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.04398em;">z</span></span></span></span> rational. This only occurs if the discriminant</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>−</mo><mn>4</mn><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo stretchy="false">(</mo><mo>−</mo><mi>n</mi><mo stretchy="false">)</mo><mo>=</mo><mn>5</mn><msup><mi>n</mi><mn>2</mn></msup><mo>+</mo><mn>2</mn><mi>n</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">(n + 1)^2 - 4(n)(-n) = 5 n^2 + 2 n + 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">4</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span><span class="mopen">(</span><span class="mord">−</span><span class="mord mathnormal">n</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span></span>
</blockquote></div>
<p>in the quadratic is the square of a rational.</p>
<p>So we now positive seek values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> such that
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><msup><mi>n</mi><mn>2</mn></msup><mo>+</mo><mn>2</mn><mi>n</mi><mo>+</mo><mn>1</mn><mo>=</mo><msup><mi>m</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">5 n^2 + 2 n + 1 = m^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span> for some integer <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span>
(the value <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi></mrow><annotation encoding="application/x-tex">m</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">m</span></span></span></span> must be an integer since a rational square root
of an integer can only be an integer.) This equation is equivalent to</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>25</mn><msup><mi>n</mi><mn>2</mn></msup><mo>+</mo><mn>10</mn><mi>n</mi><mo>+</mo><mn>5</mn><mo>=</mo><mn>5</mn><msup><mi>m</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">25n^2 + 10n + 5 = 5m^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord">25</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">10</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">5</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8641079999999999em;vertical-align:0em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>which is equivalent to</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>5</mn><msup><mi>m</mi><mn>2</mn></msup><mo>−</mo><mo stretchy="false">(</mo><mn>5</mn><mi>n</mi><mo>+</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mn>4.</mn></mrow><annotation encoding="application/x-tex">5m^2 - (5 n + 1)^2 = 4.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">5</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4.</span></span></span></span></span>
</blockquote></div>
<p>This is where Conway's topograph comes in. We'll use the topograph with the
quadratic form</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mn>5</mn><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><msup><mi>y</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">f(x, y) = 5 x^2 - y^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0585479999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>to find our solutions. Note</p>
<ul>
<li>A solution is only valuable if <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo>≡</mo><mn>1</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mn>5</mn></mrow><annotation encoding="application/x-tex">y \equiv 1 \bmod{5}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65819em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord"><span class="mord">5</span></span></span></span></span>
since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo>=</mo><mn>5</mn><mi>n</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">y = 5 n + 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">5</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> must hold.</li>
<li>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mn>5</mn></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{5}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.13278em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">5</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span></span></span></span> is irrational, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> can
never take the value <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn></mrow><annotation encoding="application/x-tex">0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span></li>
<li>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo><mo>=</mo><mn>5</mn></mrow><annotation encoding="application/x-tex">f(1, 0) = 5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">5</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo><mo>=</mo><mo>−</mo><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f(0, 1) = -1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">−</span><span class="mord">1</span><span class="mpunct">,</span></span></span></span>
there is a river on the topograph and the values of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> occur
in a periodic fashion.</li>
<li>Finally, since we take pairs <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span> that occur on the
topograph, we know <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span> share no
factors.</li>
</ul>
<p>Hence solutions <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">f(x, y) = 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span> can come either come from pairs
on the topograph or by taking a pair which satisfies
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">f(x, y) = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and scaling up by a factor of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span>. We will have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mn>2</mn><mi>x</mi><mo separator="true">,</mo><mn>2</mn><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mn>2</mn><mn>2</mn></msup><mo>⋅</mo><mn>1</mn><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">f(2x, 2y) = 2^2 \cdot 1 = 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord">2</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8641079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span></span>
</blockquote></div>
<p>due to the homogeneity of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span>.</p>
<p>Starting from the trivial base <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">u = (1, 0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">u</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">v = (0, 1),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> the full period of the river has length
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>8</mn></mrow><annotation encoding="application/x-tex">8</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">8</span></span></span></span> as seen below:</p>
<div style="text-align: center;">
<p><img alt="Golden Nugget" src="/images/golden_nugget.png"></p>
</div>
<blockquote>
<p><strong>NOTE</strong>: In the above, the values denoted as combinations of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi></mrow><annotation encoding="application/x-tex">u</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">u</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi></mrow><annotation encoding="application/x-tex">v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span> are the vectors for each face
on the topograph while the numbers are the values of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> on
these vectors.</p>
</blockquote>
<p>Since every edge protruding from the river on the positive side has a value of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn></mrow><annotation encoding="application/x-tex">4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span> on a side — the value pairs are
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>5</mn><mo separator="true">,</mo><mn>4</mn><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">(5, 4),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">5</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>4</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">(4, 1),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>4</mn><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">(1, 4),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>4</mn><mo separator="true">,</mo><mn>5</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(4, 5)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">5</span><span class="mclose">)</span></span></span></span> — by the
climbing lemma, we know all values above
those on the river have value greater than <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn></mrow><annotation encoding="application/x-tex">4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span>. Thus, the only
solutions we are concerned with</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mspace width="1em"/><mtext>or</mtext><mspace width="1em"/><mn>4</mn></mrow><annotation encoding="application/x-tex">f(x, y) = 1 \quad \text{or} \quad 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:1em;"></span><span class="mord text"><span class="mord">or</span></span><span class="mspace" style="margin-right:1em;"></span><span class="mord">4</span></span></span></span></span>
</blockquote></div>
<p>must appear on the river. Notice on the river, the
trivial base <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>u</mi><mo separator="true">,</mo><mi>v</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(u, v)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">u</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mclose">)</span></span></span></span> is replaced by the base
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>9</mn><mi>u</mi><mo>+</mo><mn>20</mn><mi>v</mi><mo separator="true">,</mo><mn>4</mn><mi>u</mi><mo>+</mo><mn>9</mn><mi>v</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(9 u + 20 v, 4 u + 9 v)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">9</span><span class="mord mathnormal">u</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">20</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mord mathnormal">u</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">9</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mclose">)</span></span></span></span>. This actually gives us a concrete
recurrence for the river and with it we can get a complete understanding of our
solution set.</p>
<p>When we start from the trivial base, we only need consider moving to the right
(orientation provided by the above picture) along the river since we only care
about the absolute value of the coordinates — <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span> comes
from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">y,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mpunct">,</span></span></span></span> so it must be positive. As such, we have a sequence
of bases <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mrow><mo fence="true">{</mo><mo stretchy="false">(</mo><msub><mi>u</mi><mi>k</mi></msub><mo separator="true">,</mo><msub><mi>v</mi><mi>k</mi></msub><mo stretchy="false">)</mo><mo fence="true">}</mo></mrow><mrow><mi>k</mi><mo>≥</mo><mn>0</mn></mrow></msub></mrow><annotation encoding="application/x-tex">\left\{(u_k, v_k)\right\}_{k \geq 0}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.144879em;vertical-align:-0.394879em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.1864079999999999em;"><span style="top:-2.4003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mrel mtight">≥</span><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.394879em;"><span></span></span></span></span></span></span></span></span></span> with
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">u_0 = (1, 0),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>v</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">v_0 = (0, 1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span> and recurrence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mn>9</mn><msub><mi>u</mi><mi>k</mi></msub><mo>+</mo><mn>20</mn><msub><mi>v</mi><mi>k</mi></msub></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>v</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mn>4</mn><msub><mi>u</mi><mi>k</mi></msub><mo>+</mo><mn>9</mn><msub><mi>v</mi><mi>k</mi></msub><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}u_{k + 1} &= 9 u_k + 20 v_k \\ v_{k + 1} &= 4 u_k + 9 v_k. \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.0000000000000004em;vertical-align:-1.2500000000000002em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">9</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">20</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>This implies that both <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><msub><mi>u</mi><mi>k</mi></msub><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">\left\{u_k\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><msub><mi>v</mi><mi>k</mi></msub><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">\left\{v_k\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span> satisfy the same relation</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>2</mn></mrow></msub><mo>−</mo><mn>9</mn><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mn>9</mn><mo stretchy="false">(</mo><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mn>9</mn><msub><mi>u</mi><mi>k</mi></msub><mo stretchy="false">)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mn>20</mn><msub><mi>v</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mn>9</mn><mo stretchy="false">(</mo><mn>20</mn><msub><mi>v</mi><mi>k</mi></msub><mo stretchy="false">)</mo><mo>=</mo><mn>20</mn><mo stretchy="false">(</mo><mn>4</mn><msub><mi>u</mi><mi>k</mi></msub><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><msub><mi>v</mi><mrow><mi>k</mi><mo>+</mo><mn>2</mn></mrow></msub><mo>−</mo><mn>9</mn><msub><mi>v</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mn>9</mn><mo stretchy="false">(</mo><msub><mi>v</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mn>9</mn><msub><mi>v</mi><mi>k</mi></msub><mo stretchy="false">)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mn>4</mn><msub><mi>u</mi><mrow><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>−</mo><mn>9</mn><mo stretchy="false">(</mo><mn>4</mn><msub><mi>u</mi><mi>k</mi></msub><mo stretchy="false">)</mo><mo>=</mo><mn>4</mn><mo stretchy="false">(</mo><mn>20</mn><msub><mi>v</mi><mi>k</mi></msub><mo stretchy="false">)</mo><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}u_{k + 2} - 9 u_{k + 1} - 9(u_{k + 1} - 9 u_k) &= 20 v_{k + 1} - 9(20 v_k) = 20(4 u_k) \\v_{k + 2} - 9 v_{k + 1} - 9(v_{k + 1} - 9 v_k) &=4 u_{k + 1} - 9(4 u_k) = 4(20 v_k). \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.0000000000000004em;vertical-align:-1.2500000000000002em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">20</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mopen">(</span><span class="mord">20</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">20</span><span class="mopen">(</span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">9</span><span class="mopen">(</span><span class="mord">4</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">4</span><span class="mopen">(</span><span class="mord">20</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>With these recurrences, you can take the three base solutions on the river and
quickly find each successive golden nugget. Since each value is a coordinate in
a vector, it satisfies the same linear recurrence as the vector. Also, since
each of the solution vectors occur as linear combinations of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mi>k</mi></msub></mrow><annotation encoding="application/x-tex">u_k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>v</mi><mi>k</mi></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">v_k,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> they must satisfy the same
recurrence as well.</p>
<p>Since the recurrence is degree two, we need the first two values to determine
the entire sequence. For the first solution we start with
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mn>0</mn></msub><mo>+</mo><msub><mi>v</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">u_0 + v_0 = (1, 1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mn>1</mn></msub><mo>+</mo><msub><mi>v</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>13</mn><mo separator="true">,</mo><mn>29</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">u_1 + v_1 = (13, 29)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">13</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">29</span><span class="mclose">)</span></span></span></span>; for the second solution we start with
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mn>0</mn></msub><mo>+</mo><mn>2</mn><msub><mi>v</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">u_0 + 2 v_0 = (1, 2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.79444em;vertical-align:-0.15em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mclose">)</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>u</mi><mn>1</mn></msub><mo>+</mo><mn>2</mn><msub><mi>v</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>17</mn><mo separator="true">,</mo><mn>38</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">u_1 + 2 v_1 = (17, 38)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.79444em;vertical-align:-0.15em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">17</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">38</span><span class="mclose">)</span></span></span></span>; and for the third solution we start
with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><msub><mi>u</mi><mn>0</mn></msub><mo>+</mo><mn>11</mn><msub><mi>v</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>5</mn><mo separator="true">,</mo><mn>11</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">5 u_0 + 11 v_0 = (5, 11)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.79444em;vertical-align:-0.15em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.79444em;vertical-align:-0.15em;"></span><span class="mord">11</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">5</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">11</span><span class="mclose">)</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><msub><mi>u</mi><mn>1</mn></msub><mo>+</mo><mn>11</mn><msub><mi>v</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>89</mn><mo separator="true">,</mo><mn>199</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">5 u_1 + 11 v_1 = (89, 199)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.79444em;vertical-align:-0.15em;"></span><span class="mord">5</span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.79444em;vertical-align:-0.15em;"></span><span class="mord">11</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">89</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">199</span><span class="mclose">)</span></span></span></span>. For the second solution, since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f(1, 2) = 1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span></span></span></span> we use homogeneity to scale up to
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>2</mn><mo separator="true">,</mo><mn>4</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(2, 4)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mclose">)</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>34</mn><mo separator="true">,</mo><mn>76</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(34, 76)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">34</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">76</span><span class="mclose">)</span></span></span></span> to start us off. With
these values, we take the second coordinate along the recurrence and get the
following values:</p>
<p><center></p>
<table>
<tbody>
<tr>
<th>n</th>
<th>First</th>
<th>Second</th>
<th>Third</th>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>4</td>
<td>11</td>
</tr>
<tr>
<td>1</td>
<td>29</td>
<td>76</td>
<td>199</td>
</tr>
<tr>
<td>2</td>
<td>521</td>
<td>1364</td>
<td>3571</td>
</tr>
<tr>
<td>3</td>
<td>9349</td>
<td>24476</td>
<td>64079</td>
</tr>
<tr>
<td>4</td>
<td>167761</td>
<td>439204</td>
<td>1149851</td>
</tr>
<tr>
<td>5</td>
<td>3010349</td>
<td>7881196</td>
<td>20633239</td>
</tr>
<tr>
<td>6</td>
<td>54018521</td>
<td>141422324</td>
<td>370248451</td>
</tr>
<tr>
<td>7</td>
<td>969323029</td>
<td>2537720636</td>
<td>6643838879</td>
</tr>
<tr>
<td>8</td>
<td>17393796001</td>
<td>45537549124</td>
<td>119218851371</td>
</tr>
<tr>
<td>9</td>
<td>312119004989</td>
<td>817138163596</td>
<td>2139295485799</td>
</tr>
<tr>
<td>10</td>
<td>5600748293801</td>
<td>14662949395604</td>
<td>38388099893011</td>
</tr>
</tbody>
</table>
<p></center></p>
<p>We don't get our fifteenth golden nugget candidate (value must be one
more than a multiple of 5) until
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5600748293801</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">5600748293801,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">5600748293801</span><span class="mpunct">,</span></span></span></span> which yields</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>n</mi><mo>=</mo><mn>1120149658760.</mn></mrow><annotation encoding="application/x-tex">n = 1120149658760.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1120149658760.</span></span></span></span></span>
</blockquote></div>
<p>By no means did I do this by hand in real life; I didn't make a pretty
representation of the river either. I just wanted to make the idea clear
without any code. To get to the code (and the way you should approach this
stuff), move on to the
<a href="/2011/08/finding-fibonacci-golden-nuggets-part-2.html">second half</a>
of this post.</p>
<h4 id="footnote">NOTE:</h4>
<p>The Fibonacci sequence is given by</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>F</mi><mi>n</mi></msub><mo>=</mo><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>F</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub><mo separator="true">,</mo><mspace width="1em"/><msub><mi>F</mi><mn>0</mn></msub><mo>=</mo><mn>0</mn><mo separator="true">,</mo><msub><mi>F</mi><mn>1</mn></msub><mo>=</mo><mn>1.</mn></mrow><annotation encoding="application/x-tex">F_n = F_{n-1} + F_{n-2}, \quad F_0 = 0, F_1 = 1.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.891661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.891661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1.</span></span></span></span></span>
</blockquote></div>Conway's Topograph Part 32011-08-23T18:00:00-07:002011-08-23T18:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-08-23:/2011/08/conways-topograph-part-3.html<p>This is the second (continued from
<a href="/2011/08/conways-topograph-part-2.html">Part 2</a>)
in a series of three blog posts. In the following we'll investigate a few
properties of an object called Conway's topograph.
<a href="http://en.wikipedia.org/wiki/John_Horton_Conway">John Conway</a> conjured up a
way to understand a binary quadratic form – a very important algebraic
object – in a geometric context …</p><p>This is the second (continued from
<a href="/2011/08/conways-topograph-part-2.html">Part 2</a>)
in a series of three blog posts. In the following we'll investigate a few
properties of an object called Conway's topograph.
<a href="http://en.wikipedia.org/wiki/John_Horton_Conway">John Conway</a> conjured up a
way to understand a binary quadratic form – a very important algebraic
object – in a geometric context. This is by no means original work, just
my interpretation of some key points from his
<a href="http://www.amazon.com/gp/product/0883850303/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0883850303&linkCode=as2&tag=boslobblo-20&linkId=5ZI7SBFQVULNR52O">The Sensual (Quadratic) Form</a><img src="//ir-na.amazon-adsystem.com/e/ir?t=boslobblo-20&l=as2&o=1&a=0883850303" width="1" height="1" border="0" alt="AMZN Affiliate Ad" style="border:none !important; margin:0px !important;" />
that I'll need for some other posts.</p>
<hr>
<h4 id="define-discriminant">Definition:</h4>
<p>For the form <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mi>a</mi><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mi>h</mi><mi>x</mi><mi>y</mi><mo>+</mo><mi>b</mi><msup><mi>y</mi><mn>2</mn></msup><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f(x, y) = a x^2 + h x y + b y^2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">h</span><span class="mord mathnormal">x</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.008548em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">b</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> we define the
<strong>discriminant</strong> as the value
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mo>−</mo><msup><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>h</mi><mo fence="true">)</mo></mrow><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">ab - \left(\frac{1}{2}h\right)^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">ab</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.404018em;vertical-align:-0.35001em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">h</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.054008em;"><span style="top:-3.3029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>The base <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1, 0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(0, 1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>
take values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span> on the form in the
Definition above and are part of a sequence with common difference
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span>. In fact, if we know the values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">a',</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>b</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">b'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> and the difference <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>h</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">h'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> at any base (edge
in the topograph), the value
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><msup><mi>b</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>−</mo><msup><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><msup><mi>h</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo fence="true">)</mo></mrow><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">a'b' - \left(\frac{1}{2}h'\right)^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.835222em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.404018em;vertical-align:-0.35001em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.054008em;"><span style="top:-3.3029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span> is independent of the
base and the direction (left or right) which determines the sign of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>h</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">h'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> and hence equal to the discriminant. To see this, first
note the sign of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>h</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">h'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> is immaterial since it is squared. Also,
consider the two other bases (edges) in the superbase. As in the proof of the
climbing lemma, one base takes values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>a</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mi>a</mi></mrow><annotation encoding="application/x-tex">a' = a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>b</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>h</mi></mrow><annotation encoding="application/x-tex">b' = a + b + h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span> with common difference
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>h</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mn>2</mn><mi>a</mi><mo>+</mo><mi>h</mi></mrow><annotation encoding="application/x-tex">h' = 2a + h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span> which gives</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><msup><mi>a</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><msup><mi>b</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>−</mo><msup><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><msup><mi>h</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo fence="true">)</mo></mrow><mn>2</mn></msup></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>a</mi><mo stretchy="false">(</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>h</mi><mo stretchy="false">)</mo><mo>−</mo><mfrac><mn>1</mn><mn>4</mn></mfrac><msup><mrow><mo fence="true">(</mo><mn>2</mn><mi>a</mi><mo>+</mo><mi>h</mi><mo fence="true">)</mo></mrow><mn>2</mn></msup></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><mi>a</mi><mi>b</mi><mo>+</mo><mi>a</mi><mi>h</mi><mo>−</mo><mrow><mo fence="true">(</mo><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><mi>a</mi><mi>h</mi><mo>+</mo><mfrac><mn>1</mn><mn>4</mn></mfrac><msup><mi>h</mi><mn>2</mn></msup><mo fence="true">)</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>a</mi><mi>b</mi><mo>−</mo><msup><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>h</mi><mo fence="true">)</mo></mrow><mn>2</mn></msup><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} a'b' - \left(\frac{1}{2}h'\right)^2 &= a(a + b + h) - \frac{1}{4}\left(2a + h\right)^2 \\ &= a^2 + a b + a h - \left(a^2 + a h + \frac{1}{4} h^2\right) \\ &= ab - \left(\frac{1}{2}h\right)^2. \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:8.508106em;vertical-align:-4.004053em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:4.504053em;"><span style="top:-6.504053000000001em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.6540080000000001em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.8040230000000004em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"></span></span><span style="top:-0.8999850000000005em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:4.004053em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:4.504053em;"><span style="top:-6.504053000000001em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">a</span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">h</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">2</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">h</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.954008em;"><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.8040230000000004em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">ab</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">ah</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">ah</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span><span style="top:-0.8999850000000005em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">ab</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">h</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.6540080000000001em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:4.004053em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Similarly the other base in the given superbase gives</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><msup><mi>a</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><msup><mi>b</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>−</mo><msup><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><msup><mi>h</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo fence="true">)</mo></mrow><mn>2</mn></msup></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mo stretchy="false">(</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>h</mi><mo stretchy="false">)</mo><mi>b</mi><mo>−</mo><mfrac><mn>1</mn><mn>4</mn></mfrac><msup><mrow><mo fence="true">(</mo><mn>2</mn><mi>b</mi><mo>+</mo><mi>h</mi><mo fence="true">)</mo></mrow><mn>2</mn></msup></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><msup><mi>b</mi><mn>2</mn></msup><mo>+</mo><mi>a</mi><mi>b</mi><mo>+</mo><mi>b</mi><mi>h</mi><mo>−</mo><mrow><mo fence="true">(</mo><msup><mi>b</mi><mn>2</mn></msup><mo>+</mo><mi>b</mi><mi>h</mi><mo>+</mo><mfrac><mn>1</mn><mn>4</mn></mfrac><msup><mi>h</mi><mn>2</mn></msup><mo fence="true">)</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>a</mi><mi>b</mi><mo>−</mo><msup><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>h</mi><mo fence="true">)</mo></mrow><mn>2</mn></msup><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} a'b' - \left(\frac{1}{2}h'\right)^2 &= (a + b + h)b - \frac{1}{4}\left(2b + h\right)^2 \\ &= b^2 + a b + b h - \left(b^2 + b h + \frac{1}{4} h^2\right) \\ &= ab - \left(\frac{1}{2}h\right)^2. \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:8.508106em;vertical-align:-4.004053em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:4.504053em;"><span style="top:-6.504053000000001em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.6540080000000001em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.8040230000000004em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"></span></span><span style="top:-0.8999850000000005em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:4.004053em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:4.504053em;"><span style="top:-6.504053000000001em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">h</span><span class="mclose">)</span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord">2</span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">h</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.954008em;"><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.8040230000000004em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">ab</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">bh</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mord mathnormal">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">bh</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span><span style="top:-0.8999850000000005em;"><span class="pstrut" style="height:3.654008em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">ab</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">h</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.6540080000000001em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:4.004053em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Having showed that there are no cycles when starting from a given
superbase, our work in understanding the topographis not complete. We
haven't actually showed that we can get from one superbase to any other
superbases within the topograph. To show this, we'll use the
discriminant and the following.</p>
<h4 id="define-well">Definition:</h4>
<p>A superbase <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi></mrow><annotation encoding="application/x-tex">W</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span></span></span></span> is called a well if all the edges at
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi></mrow><annotation encoding="application/x-tex">W</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span></span></span></span> point away from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi></mrow><annotation encoding="application/x-tex">W</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span></span></span></span>.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<div style="text-align: center;">
<p><img alt="Conway Well" src="/images/conway_well.png"></p>
</div>
<p>Notice a well is dependent on the values, hence depends on the form
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span>. In a positive-valued topograph, we may find a well by
traveling along the topograph in the opposite direction of the edges.
Eventually, we must encounter a superbase where all arrows point out (as
above), leaving us nowhere to travel and thus becoming our well. This is
because, assuming the topograph is positive-valued, we can only
decrease in value for so long (eventually the values must approach the
minimum).</p>
<h4 id="well-lemma">Lemma: (The Well Lemma)</h4>
<p>For a positive-valued form <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> and a well
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">W,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="mpunct">,</span></span></span></span> the three values
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> takes on the faces in <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi></mrow><annotation encoding="application/x-tex">W</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span></span></span></span> are the smallest
values that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> takes on the topograph.</p>
<h4 id="proof-well-lemma">Proof:</h4>
<p>Using the labels from the well in the definition above, the
<strong>Arithmetic Progression Rule</strong> for our differences gives</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>2</mn><mi>α</mi><mo>=</mo><mi>b</mi><mo>+</mo><mi>c</mi><mo>−</mo><mi>a</mi><mo separator="true">,</mo><mspace width="1em"/><mn>2</mn><mi>β</mi><mo>=</mo><mi>c</mi><mo>+</mo><mi>a</mi><mo>−</mo><mi>b</mi><mo separator="true">,</mo><mspace width="1em"/><mn>2</mn><mi>γ</mi><mo>=</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>−</mo><mi>c</mi></mrow><annotation encoding="application/x-tex">2\alpha = b + c - a, \quad 2\beta = c + a - b, \quad 2\gamma = a + b - c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">a</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">b</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">c</span></span></span></span></span>
</blockquote></div>
<p>and solving,</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>a</mi><mo>=</mo><mi>β</mi><mo>+</mo><mi>γ</mi><mo separator="true">,</mo><mspace width="1em"/><mi>b</mi><mo>=</mo><mi>α</mi><mo>+</mo><mi>γ</mi><mo separator="true">,</mo><mspace width="1em"/><mi>c</mi><mo>=</mo><mi>β</mi><mo>+</mo><mi>α</mi><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">a = \beta + \gamma, \quad b = \alpha + \gamma, \quad c = \beta + \alpha.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Let the superbase <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi><mo>=</mo><mrow><mo fence="true">{</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>3</mn></msub><mo fence="true">}</mo></mrow></mrow><annotation encoding="application/x-tex">W = \left\{e_1, e_2, e_3\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span>. Since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi></mrow><annotation encoding="application/x-tex">W</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span></span></span></span> is a superbase, we may write any vector as</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>v</mi><mo>=</mo><msub><mi>m</mi><mn>1</mn></msub><msub><mi>e</mi><mn>1</mn></msub><mo>+</mo><msub><mi>m</mi><mn>2</mn></msub><msub><mi>e</mi><mn>2</mn></msub><mo>+</mo><msub><mi>m</mi><mn>3</mn></msub><msub><mi>e</mi><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">v = m_1 e_1 + m_2 e_2 + m_3 e_3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>1</mn></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">m_1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>2</mn></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">m_2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mn>3</mn></msub><mo>∈</mo><mi mathvariant="bold">Z</mi></mrow><annotation encoding="application/x-tex">m_3 \in \mathbf{Z}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6891em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68611em;vertical-align:0em;"></span><span class="mord mathbf">Z</span></span></span></span>. Also due to the fact that
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>W</mi></mrow><annotation encoding="application/x-tex">W</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span></span></span></span> is a superbase, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>1</mn></msub><mo>+</mo><msub><mi>e</mi><mn>2</mn></msub><mo>+</mo><msub><mi>e</mi><mn>3</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">e_1 + e_2 + e_3 = (0, 0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span>
and so we may also write</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>v</mi><mo>=</mo><mo stretchy="false">(</mo><msub><mi>m</mi><mn>1</mn></msub><mo>−</mo><mi>k</mi><mo stretchy="false">)</mo><msub><mi>e</mi><mn>1</mn></msub><mo>+</mo><mo stretchy="false">(</mo><msub><mi>m</mi><mn>2</mn></msub><mo>−</mo><mi>k</mi><mo stretchy="false">)</mo><msub><mi>e</mi><mn>2</mn></msub><mo>+</mo><mo stretchy="false">(</mo><msub><mi>m</mi><mn>3</mn></msub><mo>−</mo><mi>k</mi><mo stretchy="false">)</mo><msub><mi>e</mi><mn>3</mn></msub></mrow><annotation encoding="application/x-tex">v = (m_1 - k) e_1 + (m_2 - k) e_2 + (m_3 - k) e_3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi><mo>∈</mo><mi mathvariant="bold">Z</mi></mrow><annotation encoding="application/x-tex">k \in \mathbf{Z}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68611em;vertical-align:0em;"></span><span class="mord mathbf">Z</span></span></span></span>. From this it is clear only the
differences of the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">m_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> matter. With this as our inspiration
we write</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>v</mi><mo stretchy="false">)</mo><mo>=</mo><mi>α</mi><mo stretchy="false">(</mo><msub><mi>m</mi><mn>2</mn></msub><mo>−</mo><msub><mi>m</mi><mn>3</mn></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mi>β</mi><mo stretchy="false">(</mo><msub><mi>m</mi><mn>1</mn></msub><mo>−</mo><msub><mi>m</mi><mn>3</mn></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mi>γ</mi><mo stretchy="false">(</mo><msub><mi>m</mi><mn>1</mn></msub><mo>−</mo><msub><mi>m</mi><mn>2</mn></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f(v) = \alpha(m_2 - m_3)^2 + \beta(m_1 - m_3)^2 + \gamma(m_1 - m_2)^2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span></span>
</blockquote></div>
<p>a formula discovered by Selling.</p>
<p>To verify this, notice both sides of the equation are quadratic forms in
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi></mrow><annotation encoding="application/x-tex">v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span> and</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>e</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo>=</mo><mi>a</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>β</mi><mo>+</mo><mi>γ</mi><mo>=</mo><mi>α</mi><mo>⋅</mo><msup><mn>0</mn><mn>2</mn></msup><mo>+</mo><mi>β</mi><mo>⋅</mo><msup><mn>1</mn><mn>2</mn></msup><mo>+</mo><mi>γ</mi><mo>⋅</mo><msup><mn>1</mn><mn>2</mn></msup></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>e</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo>=</mo><mi>b</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>α</mi><mo>+</mo><mi>γ</mi><mo>=</mo><mi>α</mi><mo>⋅</mo><msup><mn>1</mn><mn>2</mn></msup><mo>+</mo><mi>β</mi><mo>⋅</mo><msup><mn>0</mn><mn>2</mn></msup><mo>+</mo><mi>γ</mi><mo>⋅</mo><mo stretchy="false">(</mo><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>e</mi><mn>3</mn></msub><mo stretchy="false">)</mo><mo>=</mo><mi>c</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mi>β</mi><mo>+</mo><mi>α</mi><mo>=</mo><mi>α</mi><mo>⋅</mo><mo stretchy="false">(</mo><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mi>β</mi><mo>⋅</mo><mo stretchy="false">(</mo><mo>−</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mi>γ</mi><mo>⋅</mo><msup><mn>0</mn><mn>2</mn></msup><mi mathvariant="normal">.</mi></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned} f(e_1) = a &= \beta + \gamma = \alpha \cdot 0^2 + \beta \cdot 1^2 + \gamma \cdot 1^2 \\ f(e_2) = b &= \alpha + \gamma = \alpha \cdot 1^2 + \beta \cdot 0^2 + \gamma \cdot (-1)^2 \\ f(e_3) = c &= \beta + \alpha = \alpha \cdot (-1)^2 + \beta \cdot (-1)^2 + \gamma \cdot 0^2. \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:4.572324em;vertical-align:-2.036162em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.536162em;"><span style="top:-4.672054em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">a</span></span></span><span style="top:-3.147946em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">b</span></span></span><span style="top:-1.6238380000000001em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">c</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.036162em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.536162em;"><span style="top:-4.672054em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.147946em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord">−</span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-1.6238380000000001em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord">−</span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord">−</span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord">.</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.036162em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>hence they must be equal since both sides are quadratics that agree on
more than two points.</p>
<p>If two of the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>m</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">m_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">m</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> are equal, then <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi></mrow><annotation encoding="application/x-tex">v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span>
must be an integral multiple of the third vector, hence the value
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>v</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">f(v)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mclose">)</span></span></span></span> will be at least as largeas the value of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> on the third vector. If not, all the differences must be
nonzero (hence greater than or equal to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> in absolute value,
since integers), thus</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>v</mi><mo stretchy="false">)</mo><mo>≥</mo><mi>α</mi><mo>⋅</mo><msup><mn>1</mn><mn>2</mn></msup><mo>+</mo><mi>β</mi><mo>⋅</mo><msup><mn>1</mn><mn>2</mn></msup><mo>+</mo><mi>γ</mi><mo>⋅</mo><msup><mn>1</mn><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">f(v) \geq \alpha \cdot 1^2 + \beta \cdot 1^2 + \gamma \cdot 1^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≥</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.44445em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.63889em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8641079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">1</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>which is greater than or equal to each of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>=</mo><mi>β</mi><mo>+</mo><mi>γ</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">a = \beta + \gamma,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo>=</mo><mi>α</mi><mo>+</mo><mi>γ</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">b = \alpha + \gamma,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span><span class="mpunct">,</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mo>=</mo><mi>β</mi><mo>+</mo><mi>α</mi></mrow><annotation encoding="application/x-tex">c = \beta + \alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span></span> since all of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\alpha,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>β</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\beta,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05278em;">β</span><span class="mpunct">,</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>γ</mi></mrow><annotation encoding="application/x-tex">\gamma</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05556em;">γ</span></span></span></span> are non-negative.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<h4 id="corollary-well-lemma">Corollary:</h4>
<p>The topograph is connected; one may travel along the topograph from any given
superbase to any other.</p>
<h4 id="proof-corollary-well-lemma">Proof:</h4>
<p>Using the same quadratic form <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> as we did to show the
topograph had no cycles, we can show it is connected. Any arbitrary
superbase is on the topograph, hence must be in some connected component
of the topograph, but there may be more than one component. Since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> is positive-valued, we must have some well in this
component. But, by the above, the values at a well must be the absolute lowest
values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> takes on the topograph. This implies the well must
take the values <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and shows all superbases must be in the same component.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>From this point, we will concentrate on a special type of form relevant
to our discussion. For a form <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> which takes both positive and
negative values, but never <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">0,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mpunct">,</span></span></span></span> the topograph has a special
path thatseparates the which separates the faces where takes a positive
value and those where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> takes a negative value.</p>
<h4 id="claim-river">Claim:</h4>
<p>If a form <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> takes both positive and negative values,
but not zero, then there is a unique path of connected edges separating
the positive and negative values. What's more, the values that occur on
this river do so periodically.</p>
<h4 id="proof-claim-river">Proof:</h4>
<p>Since the topograph is connected, there must be some edge
where positive and negative values meet. As we proceed along adjacent
edges, we can choose to follow a path of edges which will separate
positive and negative (each subsequent value must be positive or
negative, allowing us to "turn" left or right).</p>
<div style="text-align: center;">
<p><img alt="Conway River" src="/images/conway_river.png"></p>
</div>
<p>On first sight, there is no reason that this path should be unique.
However, with the climbing lemma in mind, starting on the positive side
of the path and moving away from the negative values, we must have only
positive values. Using the logic of the climbing lemma instead with
negative values, we similarly see that starting on the negative side and
more away from the positive values will yield all negative numbers below
the path. Hence nowhere above the path can positive and negative values
meet and similarly below. Thus the path must be unique.</p>
<p>To show this path is periodic, we must utilize the discriminant. For
each edge along the path, we have some positive value <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span></span></span></span> and a
negative <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span> (by definition of the path) and the common
difference <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span>. Thus the determinant <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> must
be negative since the product <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi></mrow><annotation encoding="application/x-tex">ab</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">ab</span></span></span></span> is, hence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mrow><mo fence="true">∣</mo><mi>D</mi><mo fence="true">∣</mo></mrow><mo>=</mo><mrow><mo fence="true">∣</mo><mi>a</mi><mi>b</mi><mo fence="true">∣</mo></mrow><mo>+</mo><msup><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>h</mi><mo fence="true">)</mo></mrow><mn>2</mn></msup><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\left|D\right| = \left|ab\right| + \left(\frac{1}{2}h\right)^2.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mclose delimcenter" style="top:0em;">∣</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal">ab</span><span class="mclose delimcenter" style="top:0em;">∣</span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.604038em;vertical-align:-0.95003em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">h</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.6540080000000001em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Thus, both <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mrow><mo fence="true">(</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>h</mi><mo fence="true">)</mo></mrow><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">\left(\frac{1}{2}h\right)^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.404018em;vertical-align:-0.35001em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal">h</span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.054008em;"><span style="top:-3.3029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">∣</mo><mi>a</mi><mi>b</mi><mo fence="true">∣</mo></mrow><annotation encoding="application/x-tex">\left|ab\right|</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal">ab</span><span class="mclose delimcenter" style="top:0em;">∣</span></span></span></span></span> are bounded by
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">∣</mo><mi>D</mi><mo fence="true">∣</mo></mrow><annotation encoding="application/x-tex">\left|D\right|</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mclose delimcenter" style="top:0em;">∣</span></span></span></span></span>. So <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">a,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">a</span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span> are bounded
by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">∣</mo><mi>D</mi><mo fence="true">∣</mo></mrow><annotation encoding="application/x-tex">\left|D\right|</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">∣</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mclose delimcenter" style="top:0em;">∣</span></span></span></span></span>. Thus we have finitely many possible
triples <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>a</mi><mo separator="true">,</mo><mi>b</mi><mo separator="true">,</mo><mi>h</mi><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">(a, b, h),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">h</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> hence some value must be repeated in the
path. This forces the path to be periodic since the triple starting from one
triple <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>a</mi><mo separator="true">,</mo><mi>b</mi><mo separator="true">,</mo><mi>h</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(a, b, h)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">h</span><span class="mclose">)</span></span></span></span> determines next triple along the path and
hence the entire path.</p>
<p>This path is so crucial that we give it it's own name.</p>
<h4 id="define-river">Definition:</h4>
<p>If a form <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> takes both positive and negative values, but not
zero, we call the path separating the positive and negative values the
<strong>river</strong>. <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>Thanks for reading, I'll make use of all this in a few days!</p>
<h4>Update 1:</h4>
<p>This material is intentionally aimed at an intermediate (think college
freshman/high school senior) audience. One can go deeper with it, and I'd
love to get more technical off the post.</p>
<h4>Update 2:</h4>
<p>All images were created with the
<a href="http://www.texample.net/tikz/examples/">tikz</a> LaTeX library and can be
compiled with native LaTeX if <code>pgf</code> is installed.</p>Conway's Topograph Part 22011-08-23T14:00:00-07:002011-08-23T14:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-08-23:/2011/08/conways-topograph-part-2.html<p>This is the second (continued from
<a href="/2011/08/conways-topograph-part-1.html">Part 1</a>)
in a series of three blog posts. In the following we'll investigate a few
properties of an object called Conway's topograph.
<a href="http://en.wikipedia.org/wiki/John_Horton_Conway">John Conway</a> conjured up a
way to understand a binary quadratic form – a very important algebraic
object – in a geometric context …</p><p>This is the second (continued from
<a href="/2011/08/conways-topograph-part-1.html">Part 1</a>)
in a series of three blog posts. In the following we'll investigate a few
properties of an object called Conway's topograph.
<a href="http://en.wikipedia.org/wiki/John_Horton_Conway">John Conway</a> conjured up a
way to understand a binary quadratic form – a very important algebraic
object – in a geometric context. This is by no means original work, just
my interpretation of some key points from his
<a href="http://www.amazon.com/gp/product/0883850303/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0883850303&linkCode=as2&tag=boslobblo-20&linkId=5ZI7SBFQVULNR52O">The Sensual (Quadratic) Form</a><img src="//ir-na.amazon-adsystem.com/e/ir?t=boslobblo-20&l=as2&o=1&a=0883850303" width="1" height="1" border="0" alt="AMZN Affiliate Ad" style="border:none !important; margin:0px !important;" />
that I'll need for some other posts.</p>
<hr>
<p>In the following, as mentioned in Part 1,</p>
<blockquote>
<p>when referring to a base/superbase, we are referring to the lax equivalent of
these notions.</p>
</blockquote>
<p>To begin to form the topograph, note each superbase
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>3</mn></msub><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">\left\{e_1, e_2, e_3\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span> contains only three bases</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mrow><mo fence="true">{</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo fence="true">}</mo></mrow><mo separator="true">,</mo><mrow><mo fence="true">{</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>3</mn></msub><mo fence="true">}</mo></mrow><mo separator="true">,</mo><mrow><mo fence="true">{</mo><msub><mi>e</mi><mn>3</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>1</mn></msub><mo fence="true">}</mo></mrow></mrow><annotation encoding="application/x-tex">\left\{e_1, e_2\right\}, \left\{e_2, e_3\right\}, \left\{e_3, e_1\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span></span>
</blockquote></div>
<p>as subsets. Going the other direction, a base
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">\left\{e_1, e_2\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span> can only possibly be contained
as a subset of two superbases:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">⟨</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><mo stretchy="false">(</mo><msub><mi>e</mi><mn>1</mn></msub><mo>+</mo><msub><mi>e</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo stretchy="false">⟩</mo><mo separator="true">,</mo><mo stretchy="false">⟨</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><mo stretchy="false">(</mo><msub><mi>e</mi><mn>1</mn></msub><mo>−</mo><msub><mi>e</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo stretchy="false">⟩</mo><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\langle e_1, e_2, (e_1 + e_2)\rangle, \langle e_1, e_2, (e_1 - e_2)\rangle.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⟨</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)⟩</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">⟨</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)⟩</span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>With these two facts in hand, we can begin to form the geometric structure of
the topograph. The interactions between bases and superbases (as well as the
individual vectors themselves) give us the form. In the graph, we join each
superbase <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mo>◯</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(\bigcirc)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">◯</span><span class="mclose">)</span></span></span></span> to the three bases
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi mathvariant="normal">□</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(\square)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord amsrm">□</span><span class="mclose">)</span></span></span></span> in it.</p>
<div style="text-align: center;">
<p><img alt="Conways Edges and Nodes" src="/images/conway_edges_nodes.png"></p>
</div>
<p>Each edge connecting two superbases <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mo>◯</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(\bigcirc)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">◯</span><span class="mclose">)</span></span></span></span>
represents a base and we mark each of these edges with a
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi mathvariant="normal">□</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(\square)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord amsrm">□</span><span class="mclose">)</span></span></span></span> in the middle. Since each base can only be
in two superbases, we have well-defined endpoints for each base (edge).
Similarly, since each superbase contains three bases as subsets, each
superbase (endpoint) has three bases (edges) coming out of it.</p>
<div style="text-align: center;">
<p><img alt="Conway Faces" src="/images/conway_face.png"></p>
</div>
<p>As we traverse each edge (base) surrounding a given vector
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msub><mi>e</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">(e_1),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> we move from superbase (vertex) to superbase
(vertex), and form a face. Starting from a base <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">e_1, e_2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span>
traveling along each of the new faces encountered we begin to form the full
(labeled) topograph below:</p>
<div style="text-align: center;">
<p><img alt="Conway Growing the Topograph" src="/images/conway_growing_graph.png"></p>
</div>
<p>Notice the <strong>values</strong> of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> on the combinations of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">e_1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>2</mn></msub></mrow><annotation encoding="application/x-tex">e_2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is immaterial to the above
discussion, hence the shape of the topograph doesn't depend on
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span>.</p>
<p>If we know the values of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> at some superbase, it is actually
possible to find the values of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> at vectors (faces) we
encounter on the topograph without actually knowing <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span>.</p>
<h4 id="claim-arith-prog-rule">Claim:</h4>
<p>For vectors <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>v</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>v</mi><mn>2</mn></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">v_1, v_2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span></p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>v</mi><mn>1</mn></msub><mo>+</mo><msub><mi>v</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo>+</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>v</mi><mn>1</mn></msub><mo>−</mo><msub><mi>v</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo>=</mo><mn>2</mn><mrow><mo fence="true">(</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>v</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo>+</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>v</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">f(v_1 + v_2) + f(v_1 - v_2) = 2\left(f(v_1) + f(v_2)\right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mclose delimcenter" style="top:0em;">)</span></span></span></span></span></span>
</blockquote></div>
<h4 id="proof-arith-prog-rule">Proof:</h4>
<p>Exercise. (If you really can't get it, let me know in the comments.)
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>This implies that if</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>a</mi><mo>=</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>v</mi><mn>1</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo><mspace width="1em"/><mi>b</mi><mo>=</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>v</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo><mspace width="1em"/><mi>c</mi><mo>=</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>v</mi><mn>1</mn></msub><mo>+</mo><msub><mi>v</mi><mn>2</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo><mspace width="1em"/><mi>d</mi><mo>=</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>v</mi><mn>1</mn></msub><mo>−</mo><msub><mi>v</mi><mn>2</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">a = f(v_1), \quad b = f(v_2), \quad c = f(v_1 + v_2), \quad d = f(v_1 - v_2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span>
</blockquote></div>
<p>then</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>d</mi><mo separator="true">,</mo><mtext> </mtext><mi>a</mi><mo>+</mo><mi>b</mi><mo separator="true">,</mo><mtext> </mtext><mi>c</mi></mrow><annotation encoding="application/x-tex">d, \, a + b, \, c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">d</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">b</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">c</span></span></span></span></span>
</blockquote></div>
<p>form an arithmetic progression with common difference <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span>. This
so-called <strong>Arithmetic Progression Rule</strong> allows us to mark each edge with a
direction based on the value of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span>. Hence if
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi><mo><</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo><</mo><mi>c</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">d < a + b < c,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">c</span><span class="mpunct">,</span></span></span></span> we have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">h > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> and the
following directed edge:</p>
<div style="text-align: center;">
<p><img alt="Conway Directed Edge" src="/images/conway_directed_edge.png"></p>
</div>
<p>Obviously starting from a base <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">e_1, e_2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> one wonders if it is
possible to move to any pair <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span> with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span>
and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span> coprime along the topograph. It turns out that we can;
the topograph forms a structure called a tree, and all nodes are connected.</p>
<h4 id="climbing-lemma">Lemma: (Climbing Lemma)</h4>
<p>Given a superbase <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span></span></span></span> with the surrounding faces taking values
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">a,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">a</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">b,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">b</span><span class="mpunct">,</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi></mrow><annotation encoding="application/x-tex">c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">c</span></span></span></span> as below,
if <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">a,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">a</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi></mrow><annotation encoding="application/x-tex">b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span> and the common difference
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi></mrow><annotation encoding="application/x-tex">h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span> are all positive, then <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi></mrow><annotation encoding="application/x-tex">c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">c</span></span></span></span> is positive and
the other two edges at <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span></span></span></span> point away from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span></span></span></span>.</p>
<div style="text-align: center;">
<p><img alt="Conway Directed Edge Superbase" src="/images/conway_directed_edge_superbase.png"></p>
</div>
<h4 id="proof-climbing-lemma">Proof:</h4>
<p>First, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi></mrow><annotation encoding="application/x-tex">c</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">c</span></span></span></span> is positive because
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>h</mi><mo>=</mo><mi>c</mi><mo>−</mo><mo stretchy="false">(</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">h = c - (a + b),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> hence <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mo>=</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>h</mi><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">c = a + b + h > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>.
The two other edges at <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span></span></span></span> have common differences
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>a</mi><mo>+</mo><mi>c</mi><mo stretchy="false">)</mo><mo>−</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">(a + c) - b</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">c</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">b</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>b</mi><mo>+</mo><mi>c</mi><mo stretchy="false">)</mo><mo>−</mo><mi>a</mi></mrow><annotation encoding="application/x-tex">(b + c) - a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">c</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span></span></span></span>. Since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mo>=</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>h</mi></mrow><annotation encoding="application/x-tex">c = a + b + h</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">h</span></span></span></span> is greater than both <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi></mrow><annotation encoding="application/x-tex">a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">b,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">b</span><span class="mpunct">,</span></span></span></span> these differences are positive.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>Notice also that this establishes two new triples
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>a</mi><mo separator="true">,</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>h</mi><mo separator="true">,</mo><mn>2</mn><mi>a</mi><mo>+</mo><mi>h</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(a, a + b + h, 2 a + h)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">h</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">h</span><span class="mclose">)</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>b</mi><mo separator="true">,</mo><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mi>h</mi><mo separator="true">,</mo><mn>2</mn><mi>b</mi><mo>+</mo><mi>h</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(b, a + b + h, 2 b + h)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">b</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">h</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mord mathnormal">b</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">h</span><span class="mclose">)</span></span></span></span> that continue to point away
from each successive superbase and hence <strong>climb</strong> the topograph. We can
use this lemma (along with a specific form) to show that there are no
cycles in the topograph, i.e. the topograph doesn't loop back on
itself.</p>
<p>Consider the form which takes the following values at a given
superbase:</p>
<div style="text-align: center;">
<p><img alt="Conway No Cycle" src="/images/conway_no_cycle.png"></p>
</div>
<p>Due to the symmetry, we may consider traveling along an edge in any
direction from this superbase identically. Picking an arbitrary
direction, we reach the following superbase:</p>
<div style="text-align: center;">
<p><img alt="Conway Connected" src="/images/conway_connected.png"></p>
</div>
<p>Since the values must increase indefinitely as laid out by the climbing
lemma, the form can't loop back on itself; if it were to, it would need
to loop back to a smaller value. Since this holds in all directions from
the original well, there are no cycles.</p>
<p>Follow along to
<a href="/2011/08/conways-topograph-part-3.html">Part 3</a>.</p>
<h4>Update 1:</h4>
<p>This material is intentionally aimed at an intermediate (think college
freshman/high school senior) audience. One can go deeper with it, and I'd
love to get more technical off the post.</p>
<h4>Update 2:</h4>
<p>All images were created with the
<a href="http://www.texample.net/tikz/examples/">tikz</a> LaTeX library and can be
compiled with native LaTeX if <code>pgf</code> is installed.</p>Conway's Topograph Part 12011-08-23T10:00:00-07:002011-08-23T10:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-08-23:/2011/08/conways-topograph-part-1.html<p>This is the first in a series of three blog posts. In the following
we'll investigate a few properties of an object called Conway's
topograph. <a href="http://en.wikipedia.org/wiki/John_Horton_Conway">John Conway</a>
conjured up a way to understand a binary quadratic form – a very important
algebraic object – in a geometric context. This is by no …</p><p>This is the first in a series of three blog posts. In the following
we'll investigate a few properties of an object called Conway's
topograph. <a href="http://en.wikipedia.org/wiki/John_Horton_Conway">John Conway</a>
conjured up a way to understand a binary quadratic form – a very important
algebraic object – in a geometric context. This is by no means original
work, just my interpretation of some key points from his
<a href="http://www.amazon.com/gp/product/0883850303/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0883850303&linkCode=as2&tag=boslobblo-20&linkId=5ZI7SBFQVULNR52O">The Sensual (Quadratic) Form</a><img src="//ir-na.amazon-adsystem.com/e/ir?t=boslobblo-20&l=as2&o=1&a=0883850303" width="1" height="1" border="0" alt="AMZN Affiliate Ad" style="border:none !important; margin:0px !important;" />
that I'll need for some other posts.</p>
<hr>
<h4 id="define-quadratic-form">Definition:</h4>
<p>A binary quadratic form <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> is an equation of
the form:</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><mi>A</mi><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mi>H</mi><mi>x</mi><mi>y</mi><mo>+</mo><mi>B</mi><msup><mi>y</mi><mn>2</mn></msup><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">f(x, y) = A x^2 + H x y + B y^2.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">A</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.08125em;">H</span><span class="mord mathnormal">x</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0585479999999998em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>That is, a function of two variables which is homogeneous of degree two.
The coefficients <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">A,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">A</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>H</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">H,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.08125em;">H</span><span class="mpunct">,</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi></mrow><annotation encoding="application/x-tex">B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> and variables <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi></mrow><annotation encoding="application/x-tex">y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span> are often real numbers, rational numbers or integers.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>When we require the coefficients <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">A,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">A</span><span class="mpunct">,</span></span></span></span> <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>H</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">H,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.08125em;">H</span><span class="mpunct">,</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>B</mi></mrow><annotation encoding="application/x-tex">B</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span> as well as the variables <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo separator="true">,</mo><mi>y</mi></mrow><annotation encoding="application/x-tex">x, y</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span></span></span></span> to be
integers, we get an integer-valued form. In his <strong>Disquisitiones Arithmeticae</strong>,
Gauss asked (and largely answered) the fundamental question: what
integer values can each form take? For example, you may have seen the
form</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><msup><mi>y</mi><mn>2</mn></msup><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">f(x, y) = x^2 + y^2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.9474379999999999em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0585479999999998em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span></span>
</blockquote></div>
<p>where it was determined that the only primes (Gaussian primes) occuring were
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span> and those odd primes congruent to 1 modulo 4.</p>
<p>As each form <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> is homogenous degree two,
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>λ</mi><mi>x</mi><mo separator="true">,</mo><mi>λ</mi><mi>y</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>λ</mi><mn>2</mn></msup><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">f(\lambda x, \lambda y) = \lambda^2 f(x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">λ</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">λ</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">λ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span>. As a result,
if we can understand the values of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> for pairs
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span> which don't share any factors, we can understand the
entire set of values that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> takes. Also, letting
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mo>=</mo><mo>−</mo><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\lambda = -1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">λ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">−</span><span class="mord">1</span><span class="mpunct">,</span></span></span></span> there is no change in the value of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>λ</mi><mn>2</mn></msup><mo>=</mo><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\lambda^2 = 1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">λ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span></span></span></span> hence it suffices
to think of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi><mo>=</mo><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">v = (x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span> as <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>±</mo><mi>v</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\pm v,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7777700000000001em;vertical-align:-0.19444em;"></span><span class="mord">±</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mpunct">,</span></span></span></span> i.e.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo><mo separator="true">,</mo><mo stretchy="false">(</mo><mo>−</mo><mi>x</mi><mo separator="true">,</mo><mo>−</mo><mi>y</mi><mo stretchy="false">)</mo><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">\left\{(x, y), (-x, -y)\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord">−</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">−</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span>.</p>
<p>For integers <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi></mrow><annotation encoding="application/x-tex">x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">y,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mpunct">,</span></span></span></span> any point
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span> can be expressed as an integral linear combination of
the vectors <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>1</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">e_1 = (1, 0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">e_2 = (0, 1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>. So if we like, we can express all relevant
inputs for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi></mrow><annotation encoding="application/x-tex">f</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span></span> in terms of two vectors. However, instead
considering <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">,</mo><mn>1</mn><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">e_2 = (1, 1),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span> we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo>−</mo><mi>y</mi><mo stretchy="false">)</mo><mo>⋅</mo><msub><mi>e</mi><mn>1</mn></msub><mo>+</mo><mi>y</mi><mo>⋅</mo><msub><mi>e</mi><mn>2</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mi>x</mi><mo separator="true">,</mo><mi>y</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(x - y) \cdot e_1 + y \cdot e_2 = (x, y)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.63889em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mclose">)</span></span></span></span></span>
</blockquote></div>
<p>and realize a different pair <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub></mrow><annotation encoding="application/x-tex">e_1, e_2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> which again yield all
possible integer valued vectors as integral linear combinations.</p>
<h4 id="define-base">Definition:</h4>
<p>A <strong>strict base</strong> is an ordered pair <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(e_1, e_2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> whose
integral linear combinations are exactly all vectors with integer coordinates.
A <strong>lax base</strong> is a set <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">{</mo><mo>±</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><mo>±</mo><msub><mi>e</mi><mn>2</mn></msub><mo fence="true">}</mo></mrow><annotation encoding="application/x-tex">\left\{\pm e_1, \pm e_2\right\}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">{</span><span class="mord">±</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">±</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">}</span></span></span></span></span>
obtained from a strict base.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<h4 id="define-superbase">Definition:</h4>
<p>A <strong>strict superbase</strong> is an ordered triple <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>3</mn></msub><mo stretchy="false">)</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">(e_1, e_2, e_3),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mpunct">,</span></span></span></span>
for which <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>e</mi><mn>1</mn></msub><mo>+</mo><msub><mi>e</mi><mn>2</mn></msub><mo>+</mo><msub><mi>e</mi><mn>3</mn></msub><mo>=</mo><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>0</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">e_1 + e_2 + e_3 = (0, 0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">0</span><span class="mclose">)</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(e_1, e_2)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> is a strict base (i.e., with strict vectors), and
a <strong>lax superbase</strong> is a set
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">⟨</mo><mo>±</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><mo>±</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><mo>±</mo><msub><mi>e</mi><mn>3</mn></msub><mo stretchy="false">⟩</mo></mrow><annotation encoding="application/x-tex">\langle\pm e_1, \pm e_2, \pm e_3\rangle</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⟨</span><span class="mord">±</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">±</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">±</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">⟩</span></span></span></span> where
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msub><mi>e</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>2</mn></msub><mo separator="true">,</mo><msub><mi>e</mi><mn>3</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(e_1, e_2, e_3)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span> is a strict superbase.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>For our (and Conway's) purposes, it is useful to consider the lax notions and
leave the strict notions as an afterthought since a binary quadratic form is
unchanged given a sign change. From here forward, for a vector
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">v,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mpunct">,</span></span></span></span> we use the notation <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>v</mi></mrow><annotation encoding="application/x-tex">v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span> interchangeably
with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>±</mo><mi>v</mi></mrow><annotation encoding="application/x-tex">\pm v</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord">±</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span></span></span></span> and when referring to a base/superbase, we are
referring to the lax equivalent of these notions.</p>
<p>Follow along to
<a href="/2011/08/conways-topograph-part-2.html">Part 2</a>.</p>
<h4>Update:</h4>
<p>This material is intentionally aimed at an intermediate (think college
freshman/high school senior) audience. One can go deeper with it, and I'd
love to get more technical off the post.</p>The Lesson V8 Can Teach Python and Other Dynamic Languages2011-08-17T00:00:00-07:002011-08-17T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-08-17:/2011/08/lesson-v8-can-teach-python-and-other.html<p>Being unable to completely give up math for computers, I am naturally
drawn to <a href="http://projecteuler.net/">Project Euler</a> and as a result
solved a
<a href="https://github.com/dhermes/project-euler/tree/master/python/complete">ridiculous number</a>
of the problems posted there while learning Python. A few months
ago (March 13), after reading
<a href="http://jsninja.com/">Secrets of a Javascript Ninja</a>, I decided to begin
converting …</p><p>Being unable to completely give up math for computers, I am naturally
drawn to <a href="http://projecteuler.net/">Project Euler</a> and as a result
solved a
<a href="https://github.com/dhermes/project-euler/tree/master/python/complete">ridiculous number</a>
of the problems posted there while learning Python. A few months
ago (March 13), after reading
<a href="http://jsninja.com/">Secrets of a Javascript Ninja</a>, I decided to begin
converting my
<a href="https://github.com/dhermes/project-euler/commit/663ee638c6b8255d00b84173b0ecad1af2c53af1">solutions to Javascript</a>.
A month and a half later I
<a href="https://github.com/dhermes/project-euler/commit/72c092ccf82c3933944584c2479d2e7ca0ef06f7">came back</a>
to it, and then finally two months after that, I
<a href="https://github.com/dhermes/project-euler/commit/f19f85978aeeac3310b2175812d53bbea884d73b">began to take it seriously</a>.</p>
<p>After making this decision, I noticed the prime Sieve of Eratosthenes
was mighty fast when I ran it in Chrome, maybe even faster than my
beloved Python. I tabled the thought for a little, but never really
forgot it. So a few weeks ago (early August 2011), I <strong>finally</strong> got a
working install of <a href="http://nodejs.org/">node</a> running on my machine and
was able to make more of this thought. (I say <strong>finally installed</strong>
because on two previous tries I gave up because of conflicts with my
version of <code>gcc</code>, coupled with the fact that I had no good reason to use
<code>node</code>.)</p>
<p>When I originally did the conversion, I had skipped problem 8, because
my implementation required pulling in the problem data as text from a
file. While hanging out with <a href="http://twitter.com/#!/borismus">Boris</a> and
<a href="https://twitter.com/#!/ebidel">Eric</a> from on the Chrome Developer
Relations team, I decided to give it another go on node (xhr requests
not allowed) and found it to be quite simple with <code>readFileSync</code> in the
in the node native <code>fs</code> module. After witnessing this, over this weekend,
I decided to harness the power of <a href="http://code.google.com/p/v8/">V8</a> —
the Javascript engine that powers Chrome and node — and run all my
scripts locally with node. So over a two day period, I
<a href="https://github.com/dhermes/project-euler/commit/87b2cf2128be9d13d3b374d8eba9cb4ad808c982">hack-hack-hacked</a>
my way into converting the Python solutions for problems 11 through 50
(the remaining unconverted) into their Javascript equivalents, while
also converting a good portion of my hefty
<a href="https://github.com/dhermes/project-euler/blob/master/python/functions.py">functions</a>
module.</p>
<p>Once this was done, I had also found I could replace most of the nice
parts about Python with my own equivalent. For example, I was able to
replace functionality I needed from the Python <code>set</code> datatype with</p>
<div class="highlight"><pre><span></span><code><span class="kd">function</span> <span class="nx">uniq</span><span class="p">(</span><span class="nx">arr</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mf">0</span><span class="p">,</span> <span class="nx">val</span><span class="p">;</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">result</span><span class="p">[</span><span class="nx">val</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">result</span><span class="p">);</span>
<span class="p">};</span>
</code></pre></div>
<p>and I was able to replace the (amazingly) useful Python handling of <code>long</code>
integers with a non-native node package called
<a href="https://github.com/substack/node-bigint">bigint</a> that uses <code>libgmp</code>.
Of course, for Python's secret sauce — the list comprehension —
I was able to substitute enough <code>filter</code>, <code>reduce</code>, and <code>map</code> statements to
almost make it seem like I had never left Pythonland. After doing all this,
I also ended up writing my own
<a href="https://github.com/dhermes/project-euler/blob/master/javascript/operator.js">operator.js</a>
to replace the wonderful Python native module
<a href="http://docs.python.org/library/operator.html">operator</a>, and my own
<a href="https://github.com/dhermes/project-euler/blob/master/javascript/timer.js">timer.js</a>
to stand in for the Python native module
<a href="http://docs.python.org/library/time.html">time</a>.</p>
<p>Finally, I had working code and could do a side by side comparison of V8
and the Python interpreter.</p>
<blockquote>
<p><strong>Update</strong>: I added a column for <a href="http://pypy.org/">PyPy</a>, a just in time
implementation of Python.</p>
</blockquote>
<p>Here is what I found (averaging the runtime over 10 separate
calls to each function, the results are):</p>
<p><center></p>
<table>
<tbody>
<tr>
<th>Problem</th>
<th>Answer</th>
<th>Python</th>
<th>Javascript</th>
<th>Ratio (PY/JS)</th>
<th>PyPy</th>
</tr>
<tr>
<td>1\*</td>
<td>233168</td>
<td>1804ms</td>
<td>1215ms</td>
<td>1.48</td>
<td>385ms</td>
</tr>
<tr>
<td>2\*</td>
<td>4613732</td>
<td>247ms</td>
<td>102ms</td>
<td>2.42</td>
<td>85ms</td>
</tr>
<tr>
<td>3\*</td>
<td>6857</td>
<td>4725ms</td>
<td>1508ms</td>
<td>3.13</td>
<td>582ms</td>
</tr>
<tr>
<td>4</td>
<td>906609</td>
<td>8708ms</td>
<td>149ms</td>
<td>58.44</td>
<td>282ms</td>
</tr>
<tr>
<td>5\*</td>
<td>232792560</td>
<td>136ms</td>
<td>186ms</td>
<td>0.73</td>
<td>114ms</td>
</tr>
<tr>
<td>6\*</td>
<td>25164150</td>
<td>10ms</td>
<td>4ms</td>
<td>2.50</td>
<td>6ms</td>
</tr>
<tr>
<td>7</td>
<td>104743</td>
<td>656ms</td>
<td>12ms</td>
<td>54.67</td>
<td>11ms</td>
</tr>
<tr>
<td>8\*</td>
<td>40824</td>
<td>18045ms</td>
<td>5014ms</td>
<td>3.60</td>
<td>7042ms</td>
</tr>
<tr>
<td>9</td>
<td>31875000</td>
<td>610ms</td>
<td>3ms</td>
<td>203.33</td>
<td>8ms</td>
</tr>
<tr>
<td>10</td>
<td>142913828922</td>
<td>6628ms</td>
<td>167ms</td>
<td>39.69</td>
<td>116ms</td>
</tr>
<tr>
<td>11</td>
<td>70600674</td>
<td>49ms</td>
<td>2ms</td>
<td>24.50</td>
<td>11ms</td>
</tr>
<tr>
<td>12</td>
<td>76576500</td>
<td>5127ms</td>
<td>203ms</td>
<td>25.26</td>
<td>100ms</td>
</tr>
<tr>
<td>13\*</td>
<td>5537376230</td>
<td>1795ms</td>
<td>10710ms</td>
<td>0.17</td>
<td>1423ms</td>
</tr>
<tr>
<td>14</td>
<td>837799</td>
<td>5572ms</td>
<td>1712ms</td>
<td>3.25</td>
<td>362ms</td>
</tr>
<tr>
<td>15\*</td>
<td>137846528820</td>
<td>54ms</td>
<td>18ms</td>
<td>3.00</td>
<td>55ms</td>
</tr>
<tr>
<td>16\*</td>
<td>1366</td>
<td>1844ms</td>
<td>265ms</td>
<td>6.96</td>
<td>462ms</td>
</tr>
<tr>
<td>17</td>
<td>21124</td>
<td>87ms</td>
<td>4ms</td>
<td>21.75</td>
<td>7ms</td>
</tr>
<tr>
<td>18\*</td>
<td>1074</td>
<td>2291ms</td>
<td>1790ms</td>
<td>1.28</td>
<td>1090ms</td>
</tr>
<tr>
<td>19\*</td>
<td>171</td>
<td>2254ms</td>
<td>336ms</td>
<td>6.71</td>
<td>342ms</td>
</tr>
<tr>
<td>20\*</td>
<td>648</td>
<td>1061ms</td>
<td>9154ms</td>
<td>0.12</td>
<td>374ms</td>
</tr>
<tr>
<td>21</td>
<td>31626</td>
<td>18910ms</td>
<td>1038ms</td>
<td>18.22</td>
<td>728ms</td>
</tr>
<tr>
<td>22</td>
<td>871198282</td>
<td>188ms</td>
<td>7ms</td>
<td>26.86</td>
<td>8ms</td>
</tr>
<tr>
<td>23</td>
<td>4179871</td>
<td>83318ms</td>
<td>1120ms</td>
<td>74.39</td>
<td>1295ms</td>
</tr>
<tr>
<td>24\*</td>
<td>2783915460</td>
<td>206ms</td>
<td>210ms</td>
<td>0.98</td>
<td>139ms</td>
</tr>
<tr>
<td>25</td>
<td>4782</td>
<td>5865ms</td>
<td>35ms</td>
<td>167.57</td>
<td>232ms</td>
</tr>
<tr>
<td>26</td>
<td>983</td>
<td>28ms</td>
<td>18ms</td>
<td>1.56</td>
<td>4ms</td>
</tr>
<tr>
<td>27</td>
<td>-59231</td>
<td>645738ms</td>
<td>22536ms</td>
<td>28.65</td>
<td>28288ms</td>
</tr>
<tr>
<td>28\*</td>
<td>669171001</td>
<td>8509ms</td>
<td>1037ms</td>
<td>8.21</td>
<td>981ms</td>
</tr>
<tr>
<td>29</td>
<td>9183</td>
<td>184ms</td>
<td>96ms</td>
<td>1.92</td>
<td>20ms</td>
</tr>
<tr>
<td>30</td>
<td>443839</td>
<td>52167ms</td>
<td>1037ms</td>
<td>50.31</td>
<td>877ms</td>
</tr>
<tr>
<td>31</td>
<td>73682</td>
<td>9606ms</td>
<td>257ms</td>
<td>37.38</td>
<td>154ms</td>
</tr>
<tr>
<td>32</td>
<td>45228</td>
<td>206888ms</td>
<td>12096ms</td>
<td>17.10</td>
<td>4266ms</td>
</tr>
<tr>
<td>33</td>
<td>100</td>
<td>300ms</td>
<td>6ms</td>
<td>50.00</td>
<td>15ms</td>
</tr>
<tr>
<td>34</td>
<td>40730</td>
<td>7462ms</td>
<td>2447ms</td>
<td>3.05</td>
<td>247ms</td>
</tr>
<tr>
<td>35</td>
<td>55</td>
<td>8617ms</td>
<td>848ms</td>
<td>10.16</td>
<td>242ms</td>
</tr>
<tr>
<td>36</td>
<td>872187</td>
<td>189788ms</td>
<td>2183ms</td>
<td>86.94</td>
<td>3532ms</td>
</tr>
<tr>
<td>37</td>
<td>748317</td>
<td>2389022ms</td>
<td>71845ms</td>
<td>33.25</td>
<td>61551ms</td>
</tr>
<tr>
<td>38</td>
<td>932718654</td>
<td>506ms</td>
<td>10ms</td>
<td>50.60</td>
<td>12ms</td>
</tr>
<tr>
<td>39</td>
<td>840</td>
<td>178ms</td>
<td>6ms</td>
<td>29.67</td>
<td>12ms</td>
</tr>
<tr>
<td>40\*</td>
<td>210</td>
<td>326ms</td>
<td>202ms</td>
<td>1.61</td>
<td>119ms</td>
</tr>
<tr>
<td>41</td>
<td>7652413</td>
<td>2627ms</td>
<td>133ms</td>
<td>19.75</td>
<td>65ms</td>
</tr>
<tr>
<td>42</td>
<td>162</td>
<td>65ms</td>
<td>7ms</td>
<td>9.29</td>
<td>8ms</td>
</tr>
<tr>
<td>43</td>
<td>16695334890</td>
<td>38ms</td>
<td>2ms</td>
<td>19.00</td>
<td>2ms</td>
</tr>
<tr>
<td>44</td>
<td>5482660</td>
<td>384013ms</td>
<td>27744ms</td>
<td>13.84</td>
<td>6621ms</td>
</tr>
<tr>
<td>45\*</td>
<td>1533776805</td>
<td>17ms</td>
<td>4ms</td>
<td>4.25</td>
<td>8ms</td>
</tr>
<tr>
<td>46</td>
<td>5777</td>
<td>2864ms</td>
<td>202ms</td>
<td>14.18</td>
<td>65ms</td>
</tr>
<tr>
<td>47</td>
<td>134043</td>
<td>400967ms</td>
<td>12838ms</td>
<td>31.23</td>
<td>4425ms</td>
</tr>
<tr>
<td>48</td>
<td>9110846700</td>
<td>46ms</td>
<td>16ms</td>
<td>2.88</td>
<td>6ms</td>
</tr>
<tr>
<td>49</td>
<td>296962999629</td>
<td>115ms</td>
<td>8ms</td>
<td>14.38</td>
<td>13ms</td>
</tr>
<tr>
<td>50</td>
<td>997651</td>
<td>3277ms</td>
<td>80ms</td>
<td>40.96</td>
<td>51ms</td>
</tr>
<tr>
<td colspan="6">
\*These were very quick to run, so the runtimes are the time taken
to run 10000 times.
</td>
</tr>
</tbody>
</table>
<p></center></p>
<p>As you'll notice, standard Python gets its butt kicked. I was kind of
saddened by this, but in the end, just giddy that our web is faster
because of it (90% of my life is digital) and also that we can do
scripting faster on the server side (attribute to
<a href="http://twitter.com/#!/borismus">Boris Smus</a>) because of the <code>node</code> project
(thanks Ryan Dahl).</p>
<p>Standard Python is actually slower in 46 of the 50 problems. In 28 of
the 46 node is faster by a factor of 10 or greater, in 9 of those 28 by
a factor of 50 or greater and in 2 of the 9 by a factor of 100 or
greater! The only 4 in which Python was faster were from the
<strong>n = 10000</strong> sample. In fact, I was able to pinpoint exactly why:</p>
<ul>
<li>#5 - My own Javascript implementation of <code>gcd</code> is slower than the native
(<code>from fractions import gcd</code>) Python library (resulting in a
difference of 50 ms over 10000 iterations)</li>
<li>#13 - The node package <code>bigint</code> is slower than the Python native <code>long int</code>
(Javascript is slower by a factor of 6)</li>
<li>#20 - The node package <code>bigint</code> is slower than the Python native <code>long int</code>
(Javascript is slower by a factor of 8.5)</li>
<li>#24 - Having to perform two <code>slice</code>s is slower in Javascript than in
Python and there is no good way to just remove one element (resulting in
a difference of 4 ms over 10000 iterations; a little bit about that
<a href="http://ejohn.org/blog/javascript-array-remove/">here</a>)</li>
</ul>
<p>So what, you ask, is that lesson I speak of? Well, Javascript didn't
used to be this fast. How did it get that way? The brilliant and
inspired people behind V8 rethought the Javascript compile steps and
after much work, we now have code that is closer to the metal (attribute
to: <a href="https://twitter.com/#!/ebidel">Eric Bidelman</a>, i.e. closer to
machine code) than we had ever had before. The use of just-in-time
compilation and other incredible techniques has taken a formerly slow
and clunky language (Javascript) which was used well beyond its original
intended scope, and turned it into a damn fast dynamic language.
Hopefully, this movement will make its way to Python and other dynamic
languages and we can all have our code end up this close to the metal.</p>
<h4>Update 1:</h4>
<p>In response to the comments, I ran the same code on the
same machine, but with PyPy in place of Python. This is the direction I
hope standard Python goes in and commend the guys pumping out faster and
faster just in time implementations over at PyPy. I went through and
counted 20 node wins, 29 PyPy wins and 1 tie. (I reserve the right to
update the post with more detailed metrics.) While I do commend them,
the results don't really belong in this post because PyPy is still an
offshoot. (However, as I understand, they both have ties to C, as PyPy
uses <code>gcc</code> to compile to bytecode and V8 is written in C++. Feel free to
supplement my knowledge in the comments.)</p>
<h4>Update 2:</h4>
<p>All benchmarking was run on my Mac Pro Desktop with a 3.2 GHz Quad-Core
Intel Xeon processor and 4 cores for a total of12 GB 1066 MHz DDR3 memory.
I used Python version 2.6.1, node version 0.4.9, and PyPy version 1.5
(running on top of Python 2.7.1 with GCC 4.0.1).</p>Woo hoo2011-07-22T00:00:00-07:002011-07-22T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-07-22:/2011/07/woo-hoo.html<p>It's official, I am a grown up!</p>
<p><a href="http://code.google.com/apis/inapppayments/articles/index.html">http://code.google.com/apis/inapppayments/articles/index.html</a></p>Continued fraction expansions of irrational square roots2011-07-18T00:00:00-07:002011-07-18T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-07-18:/2011/07/continued-fraction-expansions-of.html<p>I had no idea (until this Thursday, July 16 2011) that I had never seen a
proof of the fact that the continued fraction expansion of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>D</mi></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span> is periodic whenever <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>
is not a perfect square. But have no fear, I found out about something …</p><p>I had no idea (until this Thursday, July 16 2011) that I had never seen a
proof of the fact that the continued fraction expansion of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>D</mi></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span> is periodic whenever <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>
is not a perfect square. But have no fear, I found out about something called a
<strong>reduced quadratic irrational</strong> and now have a proof. Here we go.</p>
<h4 id="define-reduced-quad-irr">Definition:</h4>
<p>An irrational root <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span></span> of a quadratic equation
with integer coefficients is called <strong>reduced</strong> if
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>></mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\alpha > 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and its conjugate
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover></mrow><annotation encoding="application/x-tex">\widetilde{\alpha}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6905600000000001em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span></span></span></span> satisfies
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo>−</mo><mn>1</mn><mo><</mo><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover><mo><</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">-1 < \widetilde{\alpha} < 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.7296600000000001em;vertical-align:-0.0391em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>Solutions (since assumed real) of such quadratics can be written
as</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>α</mi><mo>=</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>+</mo><mi>P</mi></mrow><mi>Q</mi></mfrac></mrow><annotation encoding="application/x-tex">\alpha = \frac{\sqrt{D} + P}{Q}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.4841050000000005em;vertical-align:-0.8804400000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6036650000000001em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">Q</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.6770000000000005em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804400000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>where <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo separator="true">,</mo><mi>P</mi><mo separator="true">,</mo><mi>Q</mi><mo>∈</mo><mi mathvariant="bold">Z</mi></mrow><annotation encoding="application/x-tex">D, P, Q \in \mathbf{Z}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68611em;vertical-align:0em;"></span><span class="mord mathbf">Z</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo separator="true">,</mo><mi>Q</mi><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">D, Q > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>. It is also possible (though not required) to ensure
that <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span></span></span></span> divides <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>−</mo><msup><mi>P</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">D - P^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>. This is
actually a necessary assumption for some of the stuff I do, is mentioned
<a href="http://en.wikipedia.org/wiki/Periodic_continued_fraction#Relation_to_quadratic_irrationals">here</a>
and generally frustrated the heck out of me, so that. As an example for some
enlightenment, notice</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>α</mi><mo>=</mo><mfrac><mrow><mn>2</mn><mo>+</mo><msqrt><mn>7</mn></msqrt></mrow><mn>4</mn></mfrac></mrow><annotation encoding="application/x-tex">\alpha = \frac{2 + \sqrt{7}}{4}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.27022em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5842200000000002em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">7</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>is reduced but <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn></mrow><annotation encoding="application/x-tex">4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span> does not divide <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>7</mn><mo>−</mo><msup><mn>2</mn><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">7 - 2^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">7</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord">2</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>.
However, if we write this as <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mn>8</mn><mo>+</mo><msqrt><mn>112</mn></msqrt></mrow><mn>16</mn></mfrac><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\frac{8 + \sqrt{112}}{16},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.3829999999999998em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0379999999999998em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">16</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.3990085em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">8</span><span class="mbin mtight">+</span><span class="mord sqrt mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.912845em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mtight" style="padding-left:0.833em;"><span class="mord mtight">112</span></span></span><span style="top:-2.872845em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail mtight" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.12715500000000002em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span></span></span></span> we
have our desired condition.</p>
<h4 id="define-associated-quad-irr">Definition:</h4>
<p>We say a reduced quadratic irrational <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span></span> is
<strong>associated</strong> to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> if we can write</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>α</mi><mo>=</mo><mfrac><mrow><mi>P</mi><mo>+</mo><msqrt><mi>D</mi></msqrt></mrow><mi>Q</mi></mfrac></mrow><annotation encoding="application/x-tex">\alpha = \frac{P + \sqrt{D}}{Q}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.4841050000000005em;vertical-align:-0.8804400000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6036650000000001em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">Q</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.6770000000000005em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804400000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span></span></span></span> divides <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>−</mo><msup><mi>P</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">D - P^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span>.
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<h4 id="lemma-1">Lemma 1:</h4>
<p>Transforming a reduced irrational root <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span></span>
associated to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> into its integer part and fractional part
via</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>α</mi><mo>=</mo><mo stretchy="false">⌊</mo><mi>α</mi><mo stretchy="false">⌋</mo><mo>+</mo><mfrac><mn>1</mn><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mfrac><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\alpha = \lfloor \alpha \rfloor + \frac{1}{\alpha'},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌊</span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mclose">⌋</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6778919999999999em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span></span></span></span></span>
</blockquote></div>
<p>the resulting quadratic irrational <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">\alpha'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> is reduced and
associated to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> as well. (This is what one does during
continued fraction expansion, and as I did with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mn>2</mn></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.13278em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span></span></span></span>
during my
<a href="/2011/07/continued-fractions-for-greater-good.html">last post</a>.)</p>
<h4 id="proof-lemma-1">Proof:</h4>
<p>Letting</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>α</mi><mo>=</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>+</mo><mi>P</mi></mrow><mi>Q</mi></mfrac></mrow><annotation encoding="application/x-tex">\alpha = \frac{\sqrt{D} + P}{Q}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.4841050000000005em;vertical-align:-0.8804400000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6036650000000001em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">Q</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.6770000000000005em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804400000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo>=</mo><mo stretchy="false">⌊</mo><mi>α</mi><mo stretchy="false">⌋</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">X =\lfloor \alpha \rfloor,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌊</span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mclose">⌋</span><span class="mpunct">,</span></span></span></span> we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><mn>1</mn><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mfrac><mo>=</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo stretchy="false">)</mo></mrow><mi>Q</mi></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\frac{1}{\alpha'} = \frac{\sqrt{D} - (QX - P)}{Q}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6778919999999999em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.4841050000000005em;vertical-align:-0.8804400000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6036650000000001em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">Q</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804400000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<ul>
<li>
<p>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>D</mi></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span> is irrational, we must have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mfrac><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\frac{1}{\alpha'} > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6828285714285715em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> and since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mfrac></mrow><annotation encoding="application/x-tex">\frac{1}{\alpha'}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6828285714285715em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> is the fractional part we know</p>
<p><div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>0</mn><mo><</mo><mfrac><mn>1</mn><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mfrac><mo><</mo><mn>1</mn><mo>⇒</mo><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>></mo><mn>1.</mn></mrow><annotation encoding="application/x-tex">0 < \frac{1}{\alpha'} < 1 \Rightarrow\alpha' > 1.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68354em;vertical-align:-0.0391em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6778919999999999em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8409920000000001em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1.</span></span></span></span></span>
</blockquote></div></p>
</li>
<li>
<p>Transforming</p>
<p><div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mfrac><mi>Q</mi><mrow><msqrt><mi>D</mi></msqrt><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo stretchy="false">)</mo></mrow></mfrac><mo>⋅</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>+</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo stretchy="false">)</mo></mrow><mrow><msqrt><mi>D</mi></msqrt><mo>+</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo stretchy="false">)</mo></mrow></mfrac><mo>=</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>+</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo stretchy="false">)</mo></mrow><mrow><mfrac><mn>1</mn><mi>Q</mi></mfrac><mrow><mo fence="true">(</mo><mi>D</mi><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo fence="true">)</mo></mrow></mrow></mfrac><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\alpha' = \frac{Q}{\sqrt{D} - (QX - P)} \cdot\frac{\sqrt{D} + (QX - P)}{\sqrt{D} + (QX - P)} = \frac{\sqrt{D} + (QX - P)}{\frac{1}{Q}\left(D - (QX - P)^2\right)},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.801892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.426995em;vertical-align:-1.066665em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.3603299999999998em;"><span style="top:-2.183335em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">Q</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.066665em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.67033em;vertical-align:-1.066665em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6036650000000001em;"><span style="top:-2.183335em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.066665em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.819881em;vertical-align:-1.216216em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6036650000000001em;"><span style="top:-2.264892em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">Q</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">)</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.216216em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span></span></span></span></span>
</blockquote></div></p>
<p>we have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>P</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi></mrow><annotation encoding="application/x-tex">P' = QX - P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>Q</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mfrac><mn>1</mn><mi>Q</mi></mfrac><mrow><mo fence="true">(</mo><mi>D</mi><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">Q' = \frac{1}{Q}\left(D - (QX - P)^2\right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.331108em;vertical-align:-0.481108em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">Q</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span> and need
to show <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>Q</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>∈</mo><mi mathvariant="bold">Z</mi></mrow><annotation encoding="application/x-tex">Q' \in \mathbf{Z}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68611em;vertical-align:0em;"></span><span class="mord mathbf">Z</span></span></span></span>. But
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>≡</mo><mi>D</mi><mo>−</mo><msup><mi>P</mi><mn>2</mn></msup><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><mi>Q</mi></mrow><annotation encoding="application/x-tex">D - (QX - P)^2 \equiv D - P^2 \bmod{Q}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">Q</span></span></span></span></span> and since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span></span> is associated to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">D,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi></mrow><annotation encoding="application/x-tex">Q</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span></span></span></span> must divide this quantity, hence <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>Q</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">Q'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span>
is an integer.</p>
</li>
<li>
<p>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo>=</mo><mo stretchy="false">⌊</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>+</mo><mi>P</mi></mrow><mi>Q</mi></mfrac><mo stretchy="false">⌋</mo></mrow><annotation encoding="application/x-tex">X = \lfloor\frac{\sqrt{D} + P}{Q}\rfloor</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.527711em;vertical-align:-0.481108em;"></span><span class="mopen">⌊</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.046603em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">Q</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord sqrt mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9322900000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mtight" style="padding-left:0.833em;"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.89229em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail mtight" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.10770999999999997em;"><span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose">⌋</span></span></span></span> is an
integer and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span></span> is irrational, we know
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo><</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>+</mo><mi>P</mi></mrow><mi>Q</mi></mfrac></mrow><annotation encoding="application/x-tex">X < \frac{\sqrt{D} + P}{Q}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72243em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.527711em;vertical-align:-0.481108em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.046603em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">Q</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord sqrt mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9322900000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mtight" style="padding-left:0.833em;"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.89229em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail mtight" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.10770999999999997em;"><span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> hence
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>P</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo><</mo><msqrt><mi>D</mi></msqrt></mrow><annotation encoding="application/x-tex">P' = QX - P < \sqrt{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72243em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span> forcing
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo><</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\widetilde{\alpha}' < 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.790992em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>.</p>
</li>
<li>
<p>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>></mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\alpha > 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> we know
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>X</mi><mo>≥</mo><mn>1</mn><mo>⇔</mo><mn>0</mn><mo>≤</mo><mi>X</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">X \geq 1 \Leftrightarrow 0 \leq X - 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8193em;vertical-align:-0.13597em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≥</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇔</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.78041em;vertical-align:-0.13597em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>. Thus</p>
<p><div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover><mo>=</mo><mfrac><mrow><mi>P</mi><mo>−</mo><msqrt><mi>D</mi></msqrt></mrow><mi>Q</mi></mfrac></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo><</mo><mn>0</mn><mo>≤</mo><mi>X</mi><mo>−</mo><mn>1</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mo>⇒</mo><mi>Q</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo><</mo><msqrt><mi>D</mi></msqrt><mo>+</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo stretchy="false">)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mo>⇒</mo><mi>Q</mi><mo stretchy="false">(</mo><msqrt><mi>D</mi></msqrt><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo><</mo><mi>D</mi><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mo>⇒</mo><mo>−</mo><msup><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><mo stretchy="false">)</mo></mrow><mrow><mfrac><mn>1</mn><mi>Q</mi></mfrac><mrow><mo fence="true">(</mo><mi>D</mi><mo>−</mo><mo stretchy="false">(</mo><mi>Q</mi><mi>X</mi><mo>−</mo><mi>P</mi><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo fence="true">)</mo></mrow></mrow></mfrac></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo><</mo><mn>1</mn></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}\widetilde{\alpha} = \frac{P - \sqrt{D}}{Q} &< 0 \leq X - 1 \\ \Rightarrow Q &< \sqrt{D} + (QX - P) \\\Rightarrow Q(\sqrt{D} - (QX - P))&< D - (QX - P)^2 \\\Rightarrow -\widetilde{\alpha}' = \frac{\sqrt{D} - (QX - P)}{\frac{1}{Q}\left(D - (QX - P)^2\right)} &< 1\end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:9.175066000000001em;vertical-align:-4.337533000000001em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:4.8375330000000005em;"><span style="top:-6.8375330000000005em;"><span class="pstrut" style="height:3.6036650000000003em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6036650000000001em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">Q</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.6770000000000005em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8804400000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-4.681553em;"><span class="pstrut" style="height:3.6036650000000003em;"></span><span class="mord"><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">Q</span></span></span><span style="top:-3.046012999999999em;"><span class="pstrut" style="height:3.6036650000000003em;"></span><span class="mord"><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">Q</span><span class="mopen">(</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9755400000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.93554em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.06445999999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">))</span></span></span><span style="top:-0.7823479999999989em;"><span class="pstrut" style="height:3.6036650000000003em;"></span><span class="mord"><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">−</span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6036650000000001em;"><span style="top:-2.264892em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">Q</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;">)</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.216216em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:4.337533000000001em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:4.8375330000000005em;"><span style="top:-6.8375330000000005em;"><span class="pstrut" style="height:3.6036650000000003em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span><span style="top:-4.681553em;"><span class="pstrut" style="height:3.6036650000000003em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9755400000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.93554em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.06445999999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose">)</span></span></span><span style="top:-3.046012999999999em;"><span class="pstrut" style="height:3.6036650000000003em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.07847em;">QX</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-0.7823479999999989em;"><span class="pstrut" style="height:3.6036650000000003em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:4.337533000000001em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div></p>
<p>hence <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>></mo><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\widetilde{\alpha}' > -1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.790992em;vertical-align:-0.0391em;"></span><span class="mord"><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord">1</span></span></span></span>
and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">\alpha'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> is reduced.</p>
</li>
<li>
<p>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>Q</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mfrac><mn>1</mn><mi>Q</mi></mfrac><mrow><mo fence="true">(</mo><mi>D</mi><mo>−</mo><mo stretchy="false">(</mo><msup><mi>P</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo fence="true">)</mo></mrow><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">Q' = \frac{1}{Q}\left(D - (P')^2\right),</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.331108em;vertical-align:-0.481108em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">Q</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span></span></span></span> we know</p>
<p><div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>D</mi><mo>−</mo><mo stretchy="false">(</mo><msup><mi>P</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>≡</mo><mi>Q</mi><msup><mi>Q</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>≡</mo><mn>0</mn><mtext> </mtext><mo lspace="0.22em" rspace="0.22em"><mrow><mi mathvariant="normal">m</mi><mi mathvariant="normal">o</mi><mi mathvariant="normal">d</mi></mrow></mo><mtext> </mtext><msup><mi>Q</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">D - (P')^2 \equiv Q Q' \equiv 0 \bmod{Q'}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.996332em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≡</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin"><span class="mord"><span class="mord mathrm">mod</span></span></span><span class="mspace" style="margin-right:0.05555555555555555em;"></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.996332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div></p>
<p>hence <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">\alpha'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> is associated to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>.</p>
</li>
</ul>
<p>Thus <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>α</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">\alpha'</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.751892em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span> is both reduced and associated to
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>. <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<h4 id="lemma-2">Lemma 2:</h4>
<p>There are finitely many reduced quadratic irrationals associated to a
fixed <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>.</p>
<h4 id="proof-lemma-2">Proof:</h4>
<p>As above write an arbitrary reduced irrational as
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>=</mo><mfrac><mrow><msqrt><mi>D</mi></msqrt><mo>+</mo><mi>P</mi></mrow><mi>Q</mi></mfrac></mrow><annotation encoding="application/x-tex">\alpha = \frac{\sqrt{D} + P}{Q}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.527711em;vertical-align:-0.481108em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.046603em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">Q</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord sqrt mtight"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9322900000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mtight" style="padding-left:0.833em;"><span class="mord mathnormal mtight" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.89229em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail mtight" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.10770999999999997em;"><span></span></span></span></span></span><span class="mbin mtight">+</span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>. Since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>></mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\alpha > 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover><mo>></mo><mo>−</mo><mn>1</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\widetilde{\alpha} > -1,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7296600000000001em;vertical-align:-0.0391em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">−</span><span class="mord">1</span><span class="mpunct">,</span></span></span></span> we know
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>+</mo><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover><mo>=</mo><mfrac><mrow><mn>2</mn><mi>P</mi></mrow><mi>Q</mi></mfrac><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\alpha + \widetilde{\alpha} = \frac{2P}{Q} > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.6905600000000001em;vertical-align:0em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.3534389999999998em;vertical-align:-0.481108em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.872331em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">Q</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mathnormal mtight" style="margin-right:0.13889em;">P</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.481108em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> hence
with the assumption <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">Q > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> we have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">P > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72243em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>.
Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mover accent="true"><mi>α</mi><mo stretchy="true">~</mo></mover><mo><</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\widetilde{\alpha} < 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7296600000000001em;vertical-align:-0.0391em;"></span><span class="mord accent"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6905600000000001em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span><span class="svg-align" style="width:calc(100% - 0.05556em);margin-left:0.05556em;top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> we also have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo><</mo><msqrt><mi>D</mi></msqrt></mrow><annotation encoding="application/x-tex">P < \sqrt{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72243em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span>. Also, since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi><mo>></mo><mn>1</mn></mrow><annotation encoding="application/x-tex">\alpha > 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>
by assumption we have <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi><mo><</mo><mi>P</mi><mo>+</mo><msqrt><mi>D</mi></msqrt><mo><</mo><mn>2</mn><msqrt><mi>D</mi></msqrt></mrow><annotation encoding="application/x-tex">Q < P + \sqrt{D} < 2\sqrt{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord">2</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span> thus
there are finitely many choices for both <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi></mrow><annotation encoding="application/x-tex">P</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">P</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>Q</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">Q,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">Q</span><span class="mpunct">,</span></span></span></span> forcing finitely many reduced quadratic irrationals
associated to a fixed <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>; the number of choices is strictly
bounded above by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi>D</mi></mrow><annotation encoding="application/x-tex">2D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>. <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<h4 id="claim-periodic">Claim:</h4>
<p>The continued fraction expansion of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>D</mi></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{D}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span> is
periodic whenever <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> is not a perfect square.</p>
<h4 id="proof-claim-periodic">Proof:</h4>
<p>We'll use Lemma 1 to establish a series of reduced quadratic irrationals
associated to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> and then use Lemma 2 to assert this
series must repeat (hence be periodic) due to the finite number of such
irrationals.</p>
<p>Write <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub><mo>=</mo><mo stretchy="false">⌊</mo><msqrt><mi>D</mi></msqrt><mo stretchy="false">⌋</mo></mrow><annotation encoding="application/x-tex">a_0 = \lfloor \sqrt{D} \rfloor</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.176665em;vertical-align:-0.25em;"></span><span class="mopen">⌊</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mclose">⌋</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>D</mi></msqrt><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><mo>+</mo><mfrac><mn>1</mn><msub><mi>α</mi><mn>0</mn></msub></mfrac></mrow><annotation encoding="application/x-tex">\sqrt{D} = a_0 + \frac{1}{\alpha_0}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.2902079999999998em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.0037em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>. From here, we will
prove</p>
<ul>
<li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">\alpha_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is a reduced quadratic irrational associated to
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span>.</li>
<li>By defining <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>=</mo><mo stretchy="false">⌊</mo><msub><mi>α</mi><mi>i</mi></msub><mo stretchy="false">⌋</mo></mrow><annotation encoding="application/x-tex">a_{i+1} = \lfloor \alpha_i \rfloor</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">⌊</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">⌋</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mi>i</mi></msub><mo>=</mo><msub><mi>a</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>+</mo><mfrac><mn>1</mn><msub><mi>α</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mfrac><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\alpha_i = a_{i + 1} + \frac{1}{\alpha_{i + 1}} ,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.791661em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.3318729999999999em;vertical-align:-0.486765em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.32808571428571426em;"><span style="top:-2.357em;margin-left:-0.0037em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.486765em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">\alpha_{i + 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span> is also a reduced quadratic
irrational associated to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> (assuming all
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>α</mi></mrow><annotation encoding="application/x-tex">\alpha</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.0037em;">α</span></span></span></span> up until <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi></mrow><annotation encoding="application/x-tex">i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.65952em;vertical-align:0em;"></span><span class="mord mathnormal">i</span></span></span></span> are as well).</li>
</ul>
<p>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><msub><mi>α</mi><mn>0</mn></msub></mfrac></mrow><annotation encoding="application/x-tex">\frac{1}{\alpha_0}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.2902079999999998em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31731428571428577em;"><span style="top:-2.357em;margin-left:-0.0037em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> is the fractional part of the
irrational <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>D</mi></msqrt><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\sqrt{D},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.121105em;vertical-align:-0.19444em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>0</mn><mo><</mo><mfrac><mn>1</mn><msub><mi>α</mi><mn>0</mn></msub></mfrac><mo><</mo><mn>1</mn><mo>⇒</mo><msub><mi>α</mi><mn>0</mn></msub><mo>></mo><mn>1.</mn></mrow><annotation encoding="application/x-tex">0 < \frac{1}{\alpha_0} < 1 \Rightarrow \alpha_0 > 1.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68354em;vertical-align:-0.0391em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.1574400000000002em;vertical-align:-0.8360000000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8360000000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.6891em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1.</span></span></span></span></span>
</blockquote></div>
<p>By simple algebra, we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>α</mi><mn>0</mn></msub><mo>=</mo><mfrac><mrow><msub><mi>a</mi><mn>0</mn></msub><mo>+</mo><msqrt><mi>D</mi></msqrt></mrow><mrow><mi>D</mi><mo>−</mo><msubsup><mi>a</mi><mn>0</mn><mn>2</mn></msubsup></mrow></mfrac><mo separator="true">,</mo><mspace width="2em"/><mover accent="true"><msub><mi>α</mi><mn>0</mn></msub><mo stretchy="true">~</mo></mover><mo>=</mo><mfrac><mrow><msub><mi>a</mi><mn>0</mn></msub><mo>−</mo><msqrt><mi>D</mi></msqrt></mrow><mrow><mi>D</mi><mo>−</mo><msubsup><mi>a</mi><mn>0</mn><mn>2</mn></msubsup></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\alpha_0 = \frac{a_0 + \sqrt{D}}{D - a_0^2}, \qquad \widetilde{\alpha_0} = \frac{a_0 - \sqrt{D}}{D - a_0^2}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.555973em;vertical-align:-0.9523079999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.603665em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7959080000000001em;"><span style="top:-2.433692em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.0448000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.26630799999999993em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9523079999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:2em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span><span class="svg-align" style="top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.555973em;vertical-align:-0.9523079999999999em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.603665em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7959080000000001em;"><span style="top:-2.433692em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.0448000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.26630799999999993em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9523079999999999em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">a_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is the floor, we know
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub><mo>−</mo><msqrt><mi>D</mi></msqrt><mo><</mo><mn>0</mn><mo>⇒</mo><mover accent="true"><msub><mi>α</mi><mn>0</mn></msub><mo stretchy="true">~</mo></mover><mo><</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">a_0 - \sqrt{D} < 0 \Rightarrow\widetilde{\alpha_0} < 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.84056em;vertical-align:-0.15em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span><span class="svg-align" style="top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span>.
Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>∈</mo><mi mathvariant="bold">Z</mi><mo>⇒</mo><msqrt><mi>D</mi></msqrt><mo>></mo><mn>1</mn></mrow><annotation encoding="application/x-tex">D \in \mathbf{Z} \Rightarrow \sqrt{D} > 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72243em;vertical-align:-0.0391em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">∈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68611em;vertical-align:0em;"></span><span class="mord mathbf">Z</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mi>D</mi></msqrt><mo>></mo><msub><mi>a</mi><mn>0</mn></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\sqrt{D} > a_0,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.11333499999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9266650000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.886665em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.11333499999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>1</mn><mo><</mo><msqrt><mi>D</mi></msqrt><mo>+</mo><msub><mi>a</mi><mn>0</mn></msub><mo>⇒</mo><msqrt><mi>D</mi></msqrt><mo>−</mo><msub><mi>a</mi><mn>0</mn></msub><mo><</mo><mi>D</mi><mo>−</mo><msubsup><mi>a</mi><mn>0</mn><mn>2</mn></msubsup></mrow><annotation encoding="application/x-tex">1 < \sqrt{D} + a_0 \Rightarrow\sqrt{D} - a_0 < D - a_0^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68354em;vertical-align:-0.0391em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.05887em;vertical-align:-0.08333em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9755400000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.93554em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.06445999999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.05887em;vertical-align:-0.08333em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9755400000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.93554em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.06445999999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.6891em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1111079999999998em;vertical-align:-0.247em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>hence</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub><mo>−</mo><msqrt><mi>D</mi></msqrt><mo>></mo><mo>−</mo><mo stretchy="false">(</mo><mi>D</mi><mo>−</mo><msubsup><mi>a</mi><mn>0</mn><mn>2</mn></msubsup><mo stretchy="false">)</mo><mo>⇒</mo><mover accent="true"><msub><mi>α</mi><mn>0</mn></msub><mo stretchy="true">~</mo></mover><mo>></mo><mo>−</mo><mn>1.</mn></mrow><annotation encoding="application/x-tex">a_0 - \sqrt{D} > -(D - a_0^2) \Rightarrow \widetilde{\alpha_0} > -1.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.06445999999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9755400000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.93554em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.06445999999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">−</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">⇒</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.84056em;vertical-align:-0.15em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69056em;"><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span><span class="svg-align" style="top:-3.43056em;"><span class="pstrut" style="height:3em;"></span><span style="height:0.26em;"><svg xmlns="http://www.w3.org/2000/svg" width='100%' height='0.26em' viewBox='0 0 600 260' preserveAspectRatio='none'><path d='M200 55.538c-77 0-168 73.953-177 73.953-3 0-7
-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0
114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0
4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128
-68.267.847-113-73.952-191-73.952z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord">1.</span></span></span></span></span>
</blockquote></div>
<p>Thus <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">\alpha_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is a reduced quadratic irrational. Since
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>P</mi><mn>0</mn></msub><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">P_0 = a_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.83333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>Q</mi><mn>0</mn></msub><mo>=</mo><mi>D</mi><mo>−</mo><msubsup><mi>a</mi><mn>0</mn><mn>2</mn></msubsup><mo>=</mo><mi>D</mi><mo>−</mo><msubsup><mi>P</mi><mn>0</mn><mn>2</mn></msubsup><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">Q_0 = D - a_0^2 = D - P_0^2,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0622159999999998em;vertical-align:-0.24810799999999997em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.4518920000000004em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0622159999999998em;vertical-align:-0.24810799999999997em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.4518920000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>Q</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">Q_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">Q</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> clearly divides <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi><mo>−</mo><msubsup><mi>P</mi><mn>0</mn><mn>2</mn></msubsup></mrow><annotation encoding="application/x-tex">D - P_0^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.0622159999999998em;vertical-align:-0.24810799999999997em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.13889em;">P</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-2.4518920000000004em;margin-left:-0.13889em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.24810799999999997em;"><span></span></span></span></span></span></span></span></span></span> so
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">\alpha_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is associated to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> as well.</p>
<p>Following the recurrence defined, since each <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">\alpha_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is a
reduced quadratic irrational, each <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mi>i</mi></msub><mo>≥</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">a_i \geq 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.7859700000000001em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≥</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>. Also, by
Lemma 1, each <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">\alpha_{i + 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span> is reduced and associated to
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>D</mi></mrow><annotation encoding="application/x-tex">D</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span></span> since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">\alpha_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> is. By Lemma 2, we only
have finitely many choices for these, hence there must be some smallest
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>k</mi></mrow><annotation encoding="application/x-tex">k</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span></span> for which <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mi>k</mi></msub><mo>=</mo><msub><mi>α</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">\alpha_k = \alpha_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>.
Since <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mrow><mi>i</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">\alpha_{i + 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span> is determined completely by
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">\alpha_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> we will then have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mrow><mi>k</mi><mo>+</mo><mi>j</mi></mrow></msub><mo>=</mo><msub><mi>α</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">\alpha_{k + j} = \alpha_j</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3361079999999999em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="mbin mtight">+</span><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.716668em;vertical-align:-0.286108em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.05724em;">j</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.286108em;"><span></span></span></span></span></span></span></span></span></span> for all <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>j</mi><mo>></mo><mn>0</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">j > 0,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mpunct">,</span></span></span></span>
hence the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">\alpha_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> are periodic. Similarly, as the
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">a_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> for <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>i</mi><mo>></mo><mn>0</mn></mrow><annotation encoding="application/x-tex">i > 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69862em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> are determined completely by
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>α</mi><mrow><mi>i</mi><mo>−</mo><mn>1</mn></mrow></msub><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\alpha_{i - 1},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.638891em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0037em;">α</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.311664em;"><span style="top:-2.5500000000000003em;margin-left:-0.0037em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mpunct">,</span></span></span></span> the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">a_i</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.31166399999999994em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> must be periodic
as well, forcing the continued fraction expansion</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msqrt><mi>D</mi></msqrt><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><mo>+</mo><mfrac><mn>1</mn><mrow><msub><mi>a</mi><mn>1</mn></msub><mo>+</mo><mfrac><mn>1</mn><mrow><msub><mi>a</mi><mn>2</mn></msub><mo>+</mo><mo>⋱</mo></mrow></mfrac></mrow></mfrac></mrow><annotation encoding="application/x-tex">\sqrt{D} = a_0 + \cfrac{1}{a_1 +\cfrac{1}{a_2 +\ddots}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.06445999999999996em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.9755400000000001em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord mathnormal" style="margin-right:0.02778em;">D</span></span></span><span style="top:-2.93554em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.06445999999999996em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:3.933em;vertical-align:-2.343em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.287em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner">⋱</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.74em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.863em;"><span></span></span></span></span></span><span></span></span></span></span><span style="top:-3.82em;"><span class="pstrut" style="height:3.59em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.33em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.343em;"><span></span></span></span></span></span><span></span></span></span></span></span></span>
</blockquote></div>
<p>to be periodic.<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<h4>Update:</h4>
<p>I
<a href="http://www.proofwiki.org/wiki/Continued_Fraction_Expansion_of_Irrational_Square_Root">posted this</a>
on ProofWiki.</p>Continued Fractions for the Greater Good part 12011-07-10T00:00:00-07:002011-07-10T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-07-10:/2011/07/continued-fractions-for-greater-good.html<p>OK, maybe not for the greater good, but still fun. This first post will
be relatively short and sweet, intended to give an introduction for the
posts that will follow.</p>
<p>Before the introduction, some
<a href="http://en.wikipedia.org/wiki/Continued_fraction#Motivation">motivation</a>
courtesy of Wikipedia:</p>
<blockquote>
<p>...decimal representation has some problems. One problem is that many
rational numbers …</p></blockquote><p>OK, maybe not for the greater good, but still fun. This first post will
be relatively short and sweet, intended to give an introduction for the
posts that will follow.</p>
<p>Before the introduction, some
<a href="http://en.wikipedia.org/wiki/Continued_fraction#Motivation">motivation</a>
courtesy of Wikipedia:</p>
<blockquote>
<p>...decimal representation has some problems. One problem is that many
rational numbers lack finite representations in this system. For
example, the number <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><mn>3</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{1}{3}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> is represented by the
infinite sequence <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>0</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mo>…</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(0, 3, 3, 3, 3, \ldots )</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mclose">)</span></span></span></span>. Another
problem is that the constant <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>10</mn></mrow><annotation encoding="application/x-tex">10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">10</span></span></span></span> is an essentially arbitrary
choice, and one which biases the resulting representation toward numbers that
have some relation to the integer <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>10</mn></mrow><annotation encoding="application/x-tex">10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">10</span></span></span></span>. For example,
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>137</mn><mn>1600</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{137}{1600}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1600</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">137</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> has a finite decimal representation,
while <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><mn>3</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{1}{3}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> does not, not because
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>137</mn><mn>1600</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{137}{1600}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1600</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">137</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> is simpler than
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><mn>3</mn></mfrac><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\frac{1}{3},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span></span></span></span> but because <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1600</mn></mrow><annotation encoding="application/x-tex">1600</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1600</span></span></span></span> happens
to divide a power of <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>10</mn></mrow><annotation encoding="application/x-tex">10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">10</span></span></span></span>
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><msup><mn>0</mn><mn>6</mn></msup><mo>=</mo><mn>1600</mn><mo>×</mo><mn>625</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(10^6 = 1600 \times 625)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">6</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1600</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">625</span><span class="mclose">)</span></span></span></span>. Continued fraction
notation is a representation of the real numbers that avoids both
these problems. Let us consider how we might describe a number like
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>415</mn><mn>93</mn></mfrac><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\frac{415}{93},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">93</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">415</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span></span></span></span> which is around <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4.4624</mn></mrow><annotation encoding="application/x-tex">4.4624</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4.4624</span></span></span></span>.
This is approximately <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn></mrow><annotation encoding="application/x-tex">4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span>. Actually it is a little bit more
than <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">4,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">4</span><span class="mpunct">,</span></span></span></span> about <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>4</mn><mo>+</mo><mfrac><mn>1</mn><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">4 + \frac{1}{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>. But the
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span> in the denominator is not correct; the correct
denominator is a little bit more than <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn></mrow><annotation encoding="application/x-tex">2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span> about
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mo>+</mo><mfrac><mn>1</mn><mn>6</mn></mfrac><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">2 + \frac{1}{6},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">6</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span></span></span></span> so <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>415</mn><mn>93</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{415}{93}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">93</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">415</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> is
approximately
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>4</mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn>2</mn><mo>+</mo><mfrac><mn>1</mn><mn>6</mn></mfrac></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">4 + \cfrac{1}{2+\cfrac{1}{6}}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:3.756em;vertical-align:-2.166em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">6</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.74em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span></span></span></span></span><span style="top:-3.82em;"><span class="pstrut" style="height:3.59em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.33em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.166em;"><span></span></span></span></span></span><span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
But the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>6</mn></mrow><annotation encoding="application/x-tex">6</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">6</span></span></span></span> in the denominator is not correct; the correct
denominator is a little bit more than <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>6</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">6,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">6</span><span class="mpunct">,</span></span></span></span> actually
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>6</mn><mo>+</mo><mfrac><mn>1</mn><mn>7</mn></mfrac></mrow><annotation encoding="application/x-tex">6+\frac{1}{7}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">6</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">7</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>. So <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>415</mn><mn>93</mn></mfrac></mrow><annotation encoding="application/x-tex">\frac{415}{93}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">93</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">415</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> is
actually
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>4</mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn>2</mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn>6</mn><mo>+</mo><mfrac><mn>1</mn><mn>7</mn></mfrac></mrow></mfrac></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">4 + \cfrac{1}{2+\cfrac{1}{6 +\cfrac{1}{7}}}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:5.236em;vertical-align:-3.646em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">6</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">7</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.74em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span></span></span></span></span><span style="top:-3.82em;"><span class="pstrut" style="height:3.59em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.33em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.166em;"><span></span></span></span></span></span><span></span></span></span></span><span style="top:-3.82em;"><span class="pstrut" style="height:3.59em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.33em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.646em;"><span></span></span></span></span></span><span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
This is exact...</p>
</blockquote>
<p>With this in mind, one can define an infinite continued fraction to be</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub><mo>+</mo><mfrac><mn>1</mn><mrow><msub><mi>a</mi><mn>1</mn></msub><mo>+</mo><mfrac><mn>1</mn><mrow><msub><mi>a</mi><mn>2</mn></msub><mo>+</mo><mo>⋱</mo></mrow></mfrac></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">a_0 + \cfrac{1}{a_1 +\cfrac{1}{a_2 +\ddots}}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:3.933em;vertical-align:-2.343em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.287em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner">⋱</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.74em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.863em;"><span></span></span></span></span></span><span></span></span></span></span><span style="top:-3.82em;"><span class="pstrut" style="height:3.59em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.33em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.343em;"><span></span></span></span></span></span><span></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>With the denominators <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub><mo separator="true">,</mo><msub><mi>a</mi><mn>1</mn></msub><mo separator="true">,</mo><msub><mi>a</mi><mn>2</mn></msub><mo separator="true">,</mo><mo>…</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">a_0, a_1, a_2, \ldots,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span></span></span></span> we can define
a recurrence for the finite approximations (convergents) of this value. For
example, the zeroth is <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">a_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and the first is</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><msub><mi>a</mi><mn>0</mn></msub><mo>+</mo><mfrac><mn>1</mn><msub><mi>a</mi><mn>1</mn></msub></mfrac><mo>=</mo><mfrac><mrow><msub><mi>a</mi><mn>0</mn></msub><msub><mi>a</mi><mn>1</mn></msub><mo>+</mo><mn>1</mn></mrow><msub><mi>a</mi><mn>1</mn></msub></mfrac><mi mathvariant="normal">.</mi></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle a_0 + \frac{1}{a_1} = \frac{a_0 a_1 + 1}{a_1}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.1574400000000002em;vertical-align:-0.8360000000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8360000000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.1574400000000002em;vertical-align:-0.8360000000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8360000000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>The other motivation (the one I actually learned first in real life) for
continued fractions comes from <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mn>2</mn></msqrt></mrow><annotation encoding="application/x-tex">\sqrt{2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.13278em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span></span></span></span> being represented by
an infinite continued fraction. (Instead of saying a probability of
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0.01876</mn><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">0.01876,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">0.01876</span><span class="mpunct">,</span></span></span></span> people would rather say a <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> in
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>53</mn></mrow><annotation encoding="application/x-tex">53</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">53</span></span></span></span> chance.) So we try to write
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msqrt><mn>2</mn></msqrt><mo>=</mo><mn>1.41421356</mn><mo>…</mo></mrow><annotation encoding="application/x-tex">\sqrt{2} = 1.41421356\ldots</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.13278em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1.41421356</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span></span></span></span> as
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mn>2.414</mn></mfrac></mrow><annotation encoding="application/x-tex">1 + \frac{1}{2.414}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.190108em;vertical-align:-0.345em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2.414</span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>. But, instead, notice that</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msqrt><mn>2</mn></msqrt><mo>=</mo><mn>1</mn><mo>+</mo><mo stretchy="false">(</mo><msqrt><mn>2</mn></msqrt><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mrow><msqrt><mn>2</mn></msqrt><mo>+</mo><mn>1</mn></mrow></mfrac><mi mathvariant="normal">.</mi></mrow><annotation encoding="application/x-tex">\sqrt{2} = 1 + (\sqrt{2} - 1) = 1 + \frac{1}{\sqrt{2} + 1}.</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.08390500000000001em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.956095em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.916095em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08390500000000001em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.206095em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.956095em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.916095em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08390500000000001em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.25144em;vertical-align:-0.93em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.2027799999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.93em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord">.</span></span></span></span></span>
</blockquote></div>
<p>Plugging this into itself, we have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msqrt><mn>2</mn></msqrt><mo>=</mo><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mrow><msqrt><mn>2</mn></msqrt><mo>+</mo><mn>1</mn></mrow></mfrac></mrow></mfrac><mo>=</mo><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mrow><msqrt><mn>2</mn></msqrt><mo>+</mo><mn>1</mn></mrow></mfrac></mrow></mfrac></mrow></mfrac></mrow><annotation encoding="application/x-tex">\sqrt{2} = 1 + \cfrac{1}{1 +1 + \cfrac{1}{\sqrt{2} + 1}} =1 + \cfrac{1}{1 +1 + \cfrac{1}{1 + 1 + \cfrac{1}{\sqrt{2} + 1}}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.08390500000000001em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.956095em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.916095em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.08390500000000001em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:4em;vertical-align:-2.41em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.2027799999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.74em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.93em;"><span></span></span></span></span></span><span></span></span></span></span><span style="top:-3.82em;"><span class="pstrut" style="height:3.59em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.33em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.41em;"><span></span></span></span></span></span><span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:5.48em;vertical-align:-3.89em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.5899999999999999em;"><span style="top:-2.2027799999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.90722em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord" style="padding-left:0.833em;"><span class="mord">2</span></span></span><span style="top:-2.86722em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702
c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14
c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54
c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10
s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429
c69,-144,104.5,-217.7,106.5,-221
l0 -0
c5.3,-9.3,12,-14,20,-14
H400000v40H845.2724
s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7
c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z
M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.13278em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.74em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.93em;"><span></span></span></span></span></span><span></span></span></span></span><span style="top:-3.82em;"><span class="pstrut" style="height:3.59em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.33em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.41em;"><span></span></span></span></span></span><span></span></span></span></span><span style="top:-3.82em;"><span class="pstrut" style="height:3.59em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.33em;"><span class="pstrut" style="height:3.59em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:3.89em;"><span></span></span></span></span></span><span></span></span></span></span></span></span>
</blockquote></div>
<p>and notice it can be represented by <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mn>1</mn><mo separator="true">;</mo><mn>2</mn><mo separator="true">,</mo><mn>2</mn><mo separator="true">,</mo><mn>2</mn><mo separator="true">,</mo><mo>…</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(1; 2, 2, 2, \ldots)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mclose">)</span></span></span></span>.</p>
<p>Define the <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">n</span></span></span></span>th convergent to be
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><msub><mi>h</mi><mi>n</mi></msub><msub><mi>k</mi><mi>n</mi></msub></mfrac><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">\frac{h_n}{k_n},</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.3413079999999997em;vertical-align:-0.44509999999999994em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8962079999999999em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:-0.03148em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.4101em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.16454285714285719em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.143em;"><span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.44509999999999994em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span></span></span></span> so above we have
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mn>0</mn></msub><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><mo separator="true">,</mo><msub><mi>k</mi><mn>0</mn></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">h_0 = a_0, k_0 = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mn>1</mn></msub><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><msub><mi>a</mi><mn>1</mn></msub><mo>+</mo><mn>1</mn><mo separator="true">,</mo><msub><mi>k</mi><mn>0</mn></msub><mo>=</mo><msub><mi>a</mi><mn>1</mn></msub></mrow><annotation encoding="application/x-tex">h_1 = a_0 a_1 + 1, k_0 = a_1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span>.</p>
<h4 id="claim">Claim:</h4>
<p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">h_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>k</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">k_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.84444em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> satisfy</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>h</mi><mi>n</mi></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><msub><mi>a</mi><mi>n</mi></msub><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>k</mi><mi>n</mi></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><msub><mi>a</mi><mi>n</mi></msub><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}h_n &= a_n h_{n - 1} + h_{n - 2} \\k_n &= a_n k_{n - 1} + k_{n - 2}\end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.0000000000000004em;vertical-align:-1.2500000000000002em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>along with <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mrow><mo>−</mo><mn>1</mn></mrow></msub><mo>=</mo><mn>1</mn><mo separator="true">,</mo><msub><mi>h</mi><mrow><mo>−</mo><mn>2</mn></mrow></msub><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">h_{-1} = 1, h_{-2} = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.902771em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.902771em;vertical-align:-0.208331em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span> and
<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>k</mi><mrow><mo>−</mo><mn>1</mn></mrow></msub><mo>=</mo><mn>0</mn><mo separator="true">,</mo><msub><mi>k</mi><mrow><mo>−</mo><mn>2</mn></mrow></msub><mo>=</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">k_{-1} = 0, k_{-2} = 1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.902771em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.902771em;vertical-align:-0.208331em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span>.</p>
<h4 id="claim-proof">Proof:</h4>
<p>The fraction <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><mfrac><msub><mi>h</mi><mi>n</mi></msub><msub><mi>k</mi><mi>n</mi></msub></mfrac></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle \frac{h_n}{k_n}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.20744em;vertical-align:-0.8360000000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8360000000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> is converted
into <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mstyle scriptlevel="0" displaystyle="true"><mfrac><msub><mi>h</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub><msub><mi>k</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub></mfrac></mstyle></mrow><annotation encoding="application/x-tex">\displaystyle \frac{h_{n + 1}}{k_{n + 1}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.265771em;vertical-align:-0.894331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.894331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span> simply by
changing <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">a_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span> to <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mi>n</mi></msub><mo>+</mo><mfrac><mn>1</mn><msub><mi>a</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub></mfrac></mrow><annotation encoding="application/x-tex">a_n + \frac{1}{a_{n + 1}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.73333em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.3318729999999999em;vertical-align:-0.486765em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3173142857142857em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.486765em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span>
in the final denominator. Since</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><msub><mi>h</mi><mi>n</mi></msub><msub><mi>k</mi><mi>n</mi></msub></mfrac><mo>=</mo><mfrac><mrow><msub><mi>a</mi><mi>n</mi></msub><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub></mrow><mrow><msub><mi>a</mi><mi>n</mi></msub><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">\frac{h_n}{k_n} = \frac{a_n h_{n - 1} + h_{n - 2}}{a_n k_{n - 1} + k_{n - 2}}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.20744em;vertical-align:-0.8360000000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.8360000000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.265771em;vertical-align:-0.894331em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.894331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span>
</blockquote></div>
<p>we similarly have</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mfrac><msub><mi>h</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub><msub><mi>k</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub></mfrac></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><mrow><mo fence="true">(</mo><msub><mi>a</mi><mi>n</mi></msub><mo>+</mo><mfrac><mn>1</mn><msub><mi>a</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub></mfrac><mo fence="true">)</mo></mrow><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub></mrow><mrow><mrow><mo fence="true">(</mo><msub><mi>a</mi><mi>n</mi></msub><mo>+</mo><mfrac><mn>1</mn><msub><mi>a</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub></mfrac><mo fence="true">)</mo></mrow><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub></mrow></mfrac></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><msub><mi>a</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub><mo stretchy="false">(</mo><msub><mi>a</mi><mi>n</mi></msub><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub><mo stretchy="false">)</mo><mo>+</mo><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub></mrow><mrow><msub><mi>a</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub><mo stretchy="false">(</mo><msub><mi>a</mi><mi>n</mi></msub><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msub><mo stretchy="false">)</mo><mo>+</mo><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub></mrow></mfrac></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><mfrac><mrow><msub><mi>a</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub><msub><mi>h</mi><mi>n</mi></msub><mo>+</mo><msub><mi>h</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub></mrow><mrow><msub><mi>a</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub><msub><mi>k</mi><mi>n</mi></msub><mo>+</mo><msub><mi>k</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msub></mrow></mfrac></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}\frac{h_{n + 1}}{k_{n + 1}} &= \frac{\left(a_n + \frac{1}{a_{n + 1}}\right)h_{n - 1} + h_{n - 2}}{\left(a_n + \frac{1}{a_{n + 1}}\right)k_{n - 1} + k_{n - 2}} \\ &= \frac{a_{n + 1}(a_n h_{n - 1} + h_{n - 2}) + h_{n - 1}}{a_{n + 1}(a_n k_{n - 1} + k_{n - 2}) + k_{n - 1}} \\&= \frac{a_{n + 1} h_n + h_{n - 1}}{a_{n + 1} k_n + k_{n - 1}}\end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:9.408811em;vertical-align:-4.4544055em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:4.9544055em;"><span style="top:-6.954405500000001em;"><span class="pstrut" style="height:4.1900200000000005em;"></span><span class="mord"><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.894331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-3.5373855000000014em;"><span class="pstrut" style="height:4.1900200000000005em;"></span><span class="mord"></span></span><span style="top:-0.9299455000000005em;"><span class="pstrut" style="height:4.1900200000000005em;"></span><span class="mord"></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:4.4544055em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:4.9544055em;"><span style="top:-6.954405500000001em;"><span class="pstrut" style="height:4.1900200000000005em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.19002em;"><span style="top:-2.11em;"><span class="pstrut" style="height:3.15em;"></span><span class="mord"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3173142857142857em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.486765em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.38em;"><span class="pstrut" style="height:3.15em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-4.1900200000000005em;"><span class="pstrut" style="height:3.15em;"></span><span class="mord"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.845108em;"><span style="top:-2.655em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.3173142857142857em;"><span style="top:-2.357em;margin-left:0em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.20252142857142857em;"><span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.486765em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.69002em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-3.5373855000000014em;"><span class="pstrut" style="height:4.1900200000000005em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span><span style="top:-0.9299455000000005em;"><span class="pstrut" style="height:4.1900200000000005em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.3139999999999996em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.894331em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:4.4544055em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>Thus <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>h</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">h_{n + 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.902771em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span> and <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>k</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub></mrow><annotation encoding="application/x-tex">k_{n + 1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.902771em;vertical-align:-0.208331em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">+</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span></span></span></span> satisfy
the same recurrence.</p>
<p>It remains to check the initial conditions work, but note</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>h</mi><mn>0</mn></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><msub><mi>h</mi><mrow><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>h</mi><mrow><mo>−</mo><mn>2</mn></mrow></msub><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><mo>⋅</mo><mn>1</mn><mo>+</mo><mn>0</mn><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>k</mi><mn>0</mn></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><msub><mi>k</mi><mrow><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>k</mi><mrow><mo>−</mo><mn>2</mn></mrow></msub><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><mo>⋅</mo><mn>0</mn><mo>+</mo><mn>1</mn><mo>=</mo><mn>1</mn></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}h_0 &= a_0 h_{-1} + h_{-2} = a_0 \cdot 1 + 0 = a_0 \\k_0 &= a_0 k_{-1} + k_{-2} = a_0 \cdot 0 + 1 = 1 \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.0000000000000004em;vertical-align:-1.2500000000000002em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">2</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>and</p>
<div class="katex-elt"><blockquote>
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mtable rowspacing="0.2500em" columnalign="right left" columnspacing="0em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>h</mi><mn>1</mn></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><msub><mi>a</mi><mn>1</mn></msub><msub><mi>h</mi><mn>0</mn></msub><mo>+</mo><msub><mi>h</mi><mrow><mo>−</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><msub><mi>a</mi><mn>1</mn></msub><mo>+</mo><mn>1</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="true"><msub><mi>k</mi><mn>1</mn></msub></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="true"><mrow><mrow></mrow><mo>=</mo><msub><mi>a</mi><mn>1</mn></msub><msub><mi>k</mi><mn>0</mn></msub><mo>+</mo><msub><mi>k</mi><mrow><mo>−</mo><mn>1</mn></mrow></msub><mo>=</mo><msub><mi>a</mi><mn>1</mn></msub><mo>⋅</mo><mn>1</mn><mo>+</mo><mn>0</mn><mo>=</mo><msub><mi>a</mi><mn>1</mn></msub></mrow></mstyle></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{aligned}h_1 &= a_1 h_{0} + h_{-1} = a_0 a_1 + 1 \\k_1 &= a_1 k_{0} + k_{-1} = a_1 \cdot 1 + 0 = a_1 \end{aligned}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.0000000000000004em;vertical-align:-1.2500000000000002em;"></span><span class="mord"><span class="mtable"><span class="col-align-r"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span><span class="col-align-l"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.7500000000000002em;"><span style="top:-3.91em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">h</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span></span></span><span style="top:-2.41em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">0</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.301108em;"><span style="top:-2.5500000000000003em;margin-left:-0.03148em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.208331em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.2500000000000002em;"><span></span></span></span></span></span></span></span></span></span></span></span>
</blockquote></div>
<p>as we checked above. <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">■</mi></mrow><annotation encoding="application/x-tex">\blacksquare</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.675em;vertical-align:0em;"></span><span class="mord amsrm">■</span></span></span></span></p>
<p>Check out my
<a href="/2011/07/continued-fraction-expansions-of.html">next post</a>,
where I actually accomplish something with fractions (or at least
prepare to accomplish something).</p>Verifying 1and1 Site Ownership with Google Apps2011-07-03T00:00:00-07:002011-07-03T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-07-03:/2011/07/verifying-1-site-ownership-with-google.html<p>Hello freens. I purchased bossylobster.com from <a href="http://1and1.com/">1&1</a>
recently with the intent of hosting it on Google App Engine. I soon
found out how delightful this process is. I made a <code>0.1</code> version for my
site at <a href="http://bossylobster.appspot.com/">bossylobster.appspot.com</a> and
decided to launch by clicking <strong>Add Domain …</strong></p><p>Hello freens. I purchased bossylobster.com from <a href="http://1and1.com/">1&1</a>
recently with the intent of hosting it on Google App Engine. I soon
found out how delightful this process is. I made a <code>0.1</code> version for my
site at <a href="http://bossylobster.appspot.com/">bossylobster.appspot.com</a> and
decided to launch by clicking <strong>Add Domain</strong> in the <strong>Application Settings</strong>.</p>
<div style="text-align: center;">
<p><img alt="Application Settings" src="/images/verify1and1_screenshot1.png"></p>
</div>
<p>After clicking this I was greeted with a note:</p>
<blockquote>
<p>You must sign up for Google Apps to register this domain or prove that you
already own it.</p>
</blockquote>
<p>Great, so now I had to sign up for Google Apps. (As a side note, at the
time this seemed an unnecessary, annoying wrinkle to add my App, but I
now realize the integration with GMail, Calendar, Docs, etc. is fantastic.)</p>
<p>So here is my ish: prove that you already own it.</p>
<p>Yesterday morning, I spent several hours trying to verify ownership of
bossylobster.com (which I had purchased a week prior). While I realize
the DNS propagation process takes some time, I didn't want to try one
method, wait 24 hours and then realize at that point it hadn't worked.</p>
<p>So, Google Apps
<a href="http://www.google.com/support/a/bin/answer.py?answer=60216">gives four options</a>
on how to verify:</p>
<ul>
<li><a href="http://www.google.com/support/a/bin/answer.py?answer=183895">Create a TXT record</a></li>
<li>Upload an HTML file to a specific path on your site</li>
<li>Add a <code><meta></code> tag to your home page</li>
<li>Verify using your Google Analytics tracking code</li>
</ul>
<p>Well, since I hadn't set my website up, the last three options were off
limits to me (or so I thought). I had a bare minimum package from 1&1,
so hosting was pretty much off limits. Apparently I picked one of the
inept domain hosts because they don't support creation of a CNAME TXT
record!! A quick Google search
<a href="http://webmasters.stackexchange.com/questions/859/how-can-i-create-an-spf-record-on-my-1and1-com-hosted-domain">reveals</a></p>
<blockquote>
<p>Yes, we do understand what an SPF record is. Unfortunately we
do not support in on our hosting plans. We apologize for any
inconvenience.</p>
</blockquote>
<div style="text-align: center;">
<p><img alt="Verify Ownership Panel" src="/images/verify1and1_screenshot2.png"></p>
</div>
<p>So here I am back to square one, just trying to prove I own something,
an inherently basic task made incredibly frustrating. Hopefully I can
help people avoid some frustration with the following instructions.</p>
<ol>
<li>Open terminal and <a href="http://ss64.com/bash/cd.html">change into the directory</a>
with code for bossylobster (your site).</li>
<li>
<p>Create a Django project in that directory via the command</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">sudo</span><span class="o">]</span><span class="w"> </span><span class="n">django</span><span class="o">-</span><span class="k">admin</span><span class="p">.</span><span class="n">py</span><span class="w"> </span><span class="n">startproject</span><span class="w"> </span><span class="n">bossylobster_django</span><span class="p">.</span><span class="w"></span>
</code></pre></div>
<p>(If you don't have Django or you are using Windows, read these
<a href="https://docs.djangoproject.com/en/1.3/intro/install/">install</a>
instructions, but DON'T SET UP A DATABASE, not necessary here. For a
more detailed tutorial see
<a href="https://docs.djangoproject.com/en/1.3/intro/tutorial01/">this page</a>. Also
note, <code>startproject</code> is the function name in the <code>django-admin</code> module and
<code>bossylobster_django</code> can be replaced with your project name.
1. Change the file <code>bossylobster_django/urls.py</code> to:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="n">patterns</span>
<span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="n">url</span>
<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s1">''</span><span class="p">,</span>
<span class="n">url</span><span class="p">(</span><span class="sa">r</span><span class="s1">'^$'</span><span class="p">,</span> <span class="s1">'bossylobster_django.views.index'</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'home'</span><span class="p">),</span>
<span class="p">)</span>
</code></pre></div>
</li>
<li>
<p>Change the file <code>bossylobster_django/views.py</code> to:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>
<span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
<span class="n">content</span> <span class="o">=</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">([</span>
<span class="s1">'<html>'</span><span class="p">,</span>
<span class="s1">' <head>'</span><span class="p">,</span>
<span class="s1">' <meta name="google-site-verification" content="XXXX" />'</span><span class="p">,</span>
<span class="s1">' </head>'</span><span class="p">,</span>
<span class="s1">' <body>'</span><span class="p">,</span>
<span class="s1">' Hello world!'</span><span class="p">,</span>
<span class="s1">' </body>'</span><span class="p">,</span>
<span class="s1">' </html>'</span><span class="p">,</span>
<span class="p">])</span>
<span class="k">return</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
</code></pre></div>
<p>where <code>XXXX</code> should be replaced by the content value provided by Google.</p>
</li>
<li>
<p><a href="http://www.bitwiseim.com/wiki/index.php?title=Determine_your_LAN_/_Local_/_Internal_IP_Address">Determine your internal IP address</a>
for use in step 6</p>
</li>
<li>
<p><a href="http://checkip.dyndns.com/">Determine your router's (external) IP address</a>
for use in step 7</p>
</li>
<li>
<p>Set up a <a href="http://portforward.com/dyndns/">port forwarding rule</a> in
your router for port 80 (<a href="https://www.grc.com/port_80.htm">websites</a>)
with the IP address you found in 4</p>
</li>
<li>
<p>(After logging in to <a href="http://1and1.com/">1&1</a>)
<a href="http://faq.1and1.com/domains/domain_admin/dns_settings/13.html">change IP for bossylobster.com</a>
to point to your router (from 5)</p>
</li>
<li>
<p>From the <code>bossylobster_django</code> directory (or whatever you called it), run
the server via</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">sudo</span><span class="o">]</span><span class="w"> </span><span class="n">python</span><span class="w"> </span><span class="n">manage</span><span class="p">.</span><span class="n">py</span><span class="w"> </span><span class="n">runserver</span><span class="w"> </span><span class="mf">192.168</span><span class="p">.</span><span class="n">XX</span><span class="p">.</span><span class="nl">YY</span><span class="p">:</span><span class="mi">80</span><span class="w"></span>
</code></pre></div>
<p>where <code>192.168.XX.YY</code> is the IP you found in 6b.</p>
</li>
<li>
<p><a href="http://www.whatsmydns.net/#A/bossylobster.com">Check</a> to see if
your change has propagated to DNS servers worldwide (wait until it has)</p>
</li>
<li>
<p>Upon propagation, login to <a href="https://www.google.com/a">Google Apps</a>
and verify via the meta tag</p>
<p><div markdown="1" style="text-align: center;">
<img alt="Verify Ownership Success" src="/images/verify1and1_screenshot3.png">
</div></p>
</li>
</ol>Getting Divvy-like functionality on Linux2011-07-01T00:00:00-07:002011-07-01T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-07-01:/2011/07/i-love-divvy-as-im-sure-many-do-but-its.html<p>I <strong>love</strong> my <a href="http://mizage.com/divvy">Divvy</a>, as I'm sure many do, but
it's not available for Linux. (I completely understand why it isn't,
though the fact that they make Divvy a <strong>free</strong> demo with full
functionality brings into question how much they are trying to monetize
it.) Anyhow, not wanting to give …</p><p>I <strong>love</strong> my <a href="http://mizage.com/divvy">Divvy</a>, as I'm sure many do, but
it's not available for Linux. (I completely understand why it isn't,
though the fact that they make Divvy a <strong>free</strong> demo with full
functionality brings into question how much they are trying to monetize
it.) Anyhow, not wanting to give away my left hand for a personal
computer, I run Ubuntu on my home machine (but OS X at work, kind of
funny).</p>
<p>In reality, all I really need from Divvy is the ability to do three
things without the mouse that I normally couldn't do.</p>
<ul>
<li>(1.) Maximize a window</li>
<li>(2a.) Make the window take the entire left half of the screen</li>
<li>(2b.) Make the window take the entire right half of the screen</li>
</ul>
<p>That's all, I'm not asking for much.</p>
<hr>
<p>As a brief side not for those who don't know, with Divvy, I start with a
window</p>
<div style="text-align: center;">
<p><img alt="Before Re-sizing with Divvy" src="/images/divvy_before.png"></p>
</div>
<p>and then call up Divvy with (a command I set globally) Ctrl-Z</p>
<div style="text-align: center;">
<p><img alt="Divvy Menu" src="/images/divvy_calldivvy.png"></p>
</div>
<p>and then once Divvy is up, I just hit the letter L (another command I
made) and voilà</p>
<div style="text-align: center;">
<p><img alt="After Re-sizing with Divvy" src="/images/divvy_after.png"></p>
</div>
<p>my window is on the full left half of the screen.</p>
<hr>
<p>So, every other weekend for the last five months, I have tried to find a
Divvy-like solution for Linux. I picked up and discarded Bluetile and
PyWO along the way, the former because it is way too heavy a solution
and the latter because it required the keypad, which my laptop keyboard
does not have (of course I could've enabled NumLock to simulate the
keypad, but that is too big a PITA).</p>
<p>Finally, last night I came to a solution that I want to share (in case
anyone has gone through the pain I have). That solution is Compiz and
here is how I did it:</p>
<ol>
<li>
<p>Install Compiz from the command line via</p>
<div class="highlight"><pre><span></span><code>sudo apt-get install compizconfig-settings-manager
</code></pre></div>
</li>
<li>
<p>Install the extra plugins via</p>
<div class="highlight"><pre><span></span><code>apt-get install compiz-fusion-plugins-extra
</code></pre></div>
</li>
<li>
<p>Open Compiz (<code>ccsm</code> from the command line) or
<div markdown="1" style="text-align: center;">
<img alt="CompixConfig Settings Manager" src="/images/ccsm.png">
</div></p>
</li>
<li>
<p>Go into the Window Management subsection
<div markdown="1" style="text-align: center;">
<img alt="Window Management Settings" src="/images/window_manage.png">
</div></p>
</li>
<li>
<p>Enter Grid and set the "Put Left" and "Put Right" bindings to Alt-F8
and Alt-F9, while disabling everything else (my choice, doesn't have to
be yours, if you have a Keypad on your keyboard and NumLock is not going
to interfere with the letter 'm', then go for it)
<div markdown="1" style="text-align: center;">
<img alt="Grid Settings" src="/images/grid.png">
</div>
(Also, another side note, if you are having trouble figuring out how to
change the binding, just click the first box, the ones that say Disabled
or whatever the current binding is and then "Grab Key Combination"
<div markdown="1" style="text-align: center;">
<img alt="Set Shortcut Value" src="/images/set_val.png">
</div>
to change the binding to your hearts content.)</p>
</li>
<li>
<p>For maximize go to General Options
<div markdown="1" style="text-align: center;">
<img alt="General Compiz Settings" src="/images/general.png">
</div></p>
</li>
<li>
<p>In the Key Bindings tab, make sure "Toggle Window Maximized" is set
to it's default value of Alt-F10
<div markdown="1" style="text-align: center;">
<img alt="Maximize Command" src="/images/maximize.png">
</div></p>
</li>
</ol>
<hr>
<p>So with that, my conditions are satisfied:</p>
<ul>
<li>Condition (1.) via Alt-F10</li>
<li>Condition (2a.) via Alt-F8</li>
<li>Condition (2b.) via Alt-F9</li>
</ul>
<p>My search is over (for now...unless I make DivvyBuntu...)</p>Life2011-06-02T00:00:00-07:002011-06-02T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-06-02:/2011/06/life.html<p>State Bird: Pterodactyl</p>First2011-04-14T00:00:00-07:002011-04-14T00:00:00-07:00Danny Hermes (dhermes@bossylobster.com)tag:blog.bossylobster.com,2011-04-14:/2011/04/first.html<p>Hi everybody!</p>