Cleaning up docs.
This commit is contained in:
parent
956d849c8a
commit
507d045a3d
|
|
@ -11775,7 +11775,9 @@ div#notebook {
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h1 id="Newton's-method"><a href="https://en.wikipedia.org/wiki/Newton%27s_method">Newton's method</a><a class="anchor-link" href="#Newton's-method">¶</a></h1>
|
||||
<h1 id="Newton's-method"><a href="https://en.wikipedia.org/wiki/Newton%27s_method">Newton's method</a><a class="anchor-link" href="#Newton's-method">¶</a></h1><p>Let's use the Newton-Raphson method for finding the root of an equation to write a function that can compute the square root of a number.</p>
|
||||
<p>Cf. <a href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">"Why Functional Programming Matters" by John Hughes</a></p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -11796,7 +11798,11 @@ div#notebook {
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<p>Cf. <a href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">"Why Functional Programming Matters" by John Hughes</a></p>
|
||||
<h2 id="A-Generator-for-Approximations">A Generator for Approximations<a class="anchor-link" href="#A-Generator-for-Approximations">¶</a></h2><p>To make a generator that generates successive approximations let’s start by assuming an initial approximation and then derive the function that computes the next approximation:</p>
|
||||
|
||||
<pre><code> a F
|
||||
---------
|
||||
a'</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -11805,6 +11811,7 @@ div#notebook {
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="A-Function-to-Compute-the-Next-Approximation">A Function to Compute the Next Approximation<a class="anchor-link" href="#A-Function-to-Compute-the-Next-Approximation">¶</a></h3><p>This is the equation for computing the next approximate value of the square root:</p>
|
||||
<p>$a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}$</p>
|
||||
|
||||
</div>
|
||||
|
|
@ -11814,22 +11821,45 @@ div#notebook {
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<p>Let's define a function that computes the above equation:</p>
|
||||
|
||||
<pre><code> n a Q
|
||||
---------------
|
||||
(a+n/a)/2
|
||||
|
||||
n a tuck / + 2 /
|
||||
<pre><code>a n over / + 2 /
|
||||
a n a / + 2 /
|
||||
a n/a + 2 /
|
||||
a+n/a 2 /
|
||||
(a+n/a)/2
|
||||
|
||||
</code></pre>
|
||||
<p>We want it to leave n but replace a, so we execute it with <code>unary</code>:</p>
|
||||
<p>The function we want has the argument <code>n</code> in it:</p>
|
||||
|
||||
<pre><code>Q == [tuck / + 2 /] unary</code></pre>
|
||||
<pre><code>F == n over / + 2 /</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Make-it-into-a-Generator">Make it into a Generator<a class="anchor-link" href="#Make-it-into-a-Generator">¶</a></h3><p>Our generator would be created by:</p>
|
||||
|
||||
<pre><code>a [dup F] make_generator
|
||||
|
||||
</code></pre>
|
||||
<p>With n as part of the function F, but n is the input to the sqrt function we’re writing. If we let 1 be the initial approximation:</p>
|
||||
|
||||
<pre><code>1 n 1 / + 2 /
|
||||
1 n/1 + 2 /
|
||||
1 n + 2 /
|
||||
n+1 2 /
|
||||
(n+1)/2
|
||||
|
||||
</code></pre>
|
||||
<p>The generator can be written as:</p>
|
||||
|
||||
<pre><code>23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 23 [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 [23 over / + 2 /] [dup] swoncat make_generator
|
||||
1 [dup 23 over / + 2 /] make_generator</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -11839,111 +11869,35 @@ a+n/a 2 /
|
|||
<div class="prompt input_prompt">In [2]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Q == [tuck / + 2 /] unary'</span><span class="p">)</span>
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'codireco == cons dip rest cons'</span><span class="p">)</span>
|
||||
<span class="n">define</span><span class="p">(</span><span class="s1">'make_generator == [codireco] ccons'</span><span class="p">)</span>
|
||||
<span class="n">define</span><span class="p">(</span><span class="s1">'ccons == cons cons'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<p>And a function to compute the error:</p>
|
||||
|
||||
<pre><code>n a sqr - abs
|
||||
|n-a**2|
|
||||
|
||||
</code></pre>
|
||||
<p>This should be <code>nullary</code> so as to leave both n and a on the stack below the error.</p>
|
||||
|
||||
<pre><code>err == [sqr - abs] nullary</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [3]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'err == [sqr - abs] nullary'</span><span class="p">)</span>
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<p>Now we can define a recursive program that expects a number <code>n</code>, an initial estimate <code>a</code>, and an epsilon value <code>ε</code>, and that leaves on the stack the square root of <code>n</code> to within the precision of the epsilon value. (Later on we'll refine it to generate the initial estimate and hard-code an epsilon value.)</p>
|
||||
|
||||
<pre><code>n a ε square-root
|
||||
-----------------
|
||||
√n
|
||||
|
||||
|
||||
</code></pre>
|
||||
<p>If we apply the two functions <code>Q</code> and <code>err</code> defined above we get the next approximation and the error on the stack below the epsilon.</p>
|
||||
|
||||
<pre><code>n a ε [Q err] dip
|
||||
n a Q err ε
|
||||
n a' err ε
|
||||
n a' e ε
|
||||
|
||||
</code></pre>
|
||||
<p>Let's define the recursive function from here. Start with <code>ifte</code>; the predicate and the base case behavior are obvious:</p>
|
||||
|
||||
<pre><code>n a' e ε [<] [popop popd] [J] ifte
|
||||
|
||||
</code></pre>
|
||||
<p>Base-case</p>
|
||||
|
||||
<pre><code>n a' e ε popop popd
|
||||
n a' popd
|
||||
a'
|
||||
|
||||
</code></pre>
|
||||
<p>The recursive branch is pretty easy. Discard the error and recur.</p>
|
||||
|
||||
<pre><code>w/ K == [<] [popop popd] [J] ifte
|
||||
|
||||
n a' e ε J
|
||||
n a' e ε popd [Q err] dip [K] i
|
||||
n a' ε [Q err] dip [K] i
|
||||
n a' Q err ε [K] i
|
||||
n a'' e ε K
|
||||
|
||||
</code></pre>
|
||||
<p>This fragment alone is pretty useful.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [4]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'K == [<] [popop popd] [popd [Q err] dip] primrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [5]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'25 10 0.001 dup K'</span><span class="p">)</span>
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
|
@ -11960,38 +11914,7 @@ n a'' e ε K
|
|||
|
||||
|
||||
<div class="output_subarea output_stream output_stdout output_text">
|
||||
<pre>5.000000232305737
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [6]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'25 10 0.000001 dup K'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="output_wrapper">
|
||||
<div class="output">
|
||||
|
||||
|
||||
<div class="output_area">
|
||||
|
||||
<div class="prompt"></div>
|
||||
|
||||
|
||||
<div class="output_subarea output_stream output_stdout output_text">
|
||||
<pre>5.000000000000005
|
||||
<pre>[1 [dup 23 over / + 2 /] codireco]
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -12004,9 +11927,101 @@ n a'' e ε K
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<p>So now all we need is a way to generate an initial approximation and an epsilon value:</p>
|
||||
<p>Let's drive the generator a few time (with the <code>x</code> combinator) and square the approximation to see how well it works...</p>
|
||||
|
||||
<pre><code>square-root == dup 3 / 0.000001 dup K</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [5]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra 6 [x popd] times first sqr'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="output_wrapper">
|
||||
<div class="output">
|
||||
|
||||
|
||||
<div class="output_area">
|
||||
|
||||
<div class="prompt"></div>
|
||||
|
||||
|
||||
<div class="output_subarea output_stream output_stdout output_text">
|
||||
<pre>23.0000000001585
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h2 id="Finding-Consecutive-Approximations-within-a-Tolerance">Finding Consecutive Approximations within a Tolerance<a class="anchor-link" href="#Finding-Consecutive-Approximations-within-a-Tolerance">¶</a></h2><blockquote><p>The remainder of a square root finder is a function <em>within</em>, which takes a tolerance and a list of approximations and looks down the list for two successive approximations that differ by no more than the given tolerance.</p>
|
||||
</blockquote>
|
||||
<p>From <a href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">"Why Functional Programming Matters" by John Hughes</a></p>
|
||||
<p>(And note that by “list” he means a lazily-evaluated list.)</p>
|
||||
<p>Using the <em>output</em> <code>[a G]</code> of the above generator for square root approximations, and further assuming that the first term a has been generated already and epsilon ε is handy on the stack...</p>
|
||||
|
||||
<pre><code> a [b G] ε within
|
||||
---------------------- a b - abs ε <=
|
||||
b
|
||||
|
||||
|
||||
a [b G] ε within
|
||||
---------------------- a b - abs ε >
|
||||
b [c G] ε within</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Predicate">Predicate<a class="anchor-link" href="#Predicate">¶</a></h3>
|
||||
<pre><code>a [b G] ε [first - abs] dip <=
|
||||
a [b G] first - abs ε <=
|
||||
a b - abs ε <=
|
||||
a-b abs ε <=
|
||||
abs(a-b) ε <=
|
||||
(abs(a-b)<=ε)</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [6]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_P == [first - abs] dip <='</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Base-Case">Base-Case<a class="anchor-link" href="#Base-Case">¶</a></h3>
|
||||
<pre><code>a [b G] ε roll< popop first
|
||||
[b G] ε a popop first
|
||||
[b G] first
|
||||
b</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -12016,82 +12031,86 @@ n a'' e ε K
|
|||
<div class="prompt input_prompt">In [7]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'square-root == dup 3 / 0.000001 dup K'</span><span class="p">)</span>
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_B == roll< popop first'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Recur">Recur<a class="anchor-link" href="#Recur">¶</a></h3>
|
||||
<pre><code>a [b G] ε R0 [within] R1
|
||||
|
||||
</code></pre>
|
||||
<ol>
|
||||
<li>Discard a.</li>
|
||||
<li>Use x combinator to generate next term from G.</li>
|
||||
<li>Run within with <code>i</code> (it is a <code>primrec</code> function.)</li>
|
||||
</ol>
|
||||
<p>Pretty straightforward:</p>
|
||||
|
||||
<pre><code>a [b G] ε R0 [within] R1
|
||||
a [b G] ε [popd x] dip [within] i
|
||||
a [b G] popd x ε [within] i
|
||||
[b G] x ε [within] i
|
||||
b [c G] ε [within] i
|
||||
b [c G] ε within
|
||||
|
||||
b [c G] ε within</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [8]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'36 square-root'</span><span class="p">)</span>
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_R == [popd x] dip'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="output_wrapper">
|
||||
<div class="output">
|
||||
|
||||
|
||||
<div class="output_area">
|
||||
|
||||
<div class="prompt"></div>
|
||||
|
||||
|
||||
<div class="output_subarea output_stream output_stdout output_text">
|
||||
<pre>6.000000000000007
|
||||
</pre>
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Setting-up">Setting up<a class="anchor-link" href="#Setting-up">¶</a></h3><p>The recursive function we have defined so far needs a slight preamble: <code>x</code> to prime the generator and the epsilon value to use:</p>
|
||||
|
||||
<pre><code>[a G] x ε ...
|
||||
a [b G] ε ...</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [9]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'4895048365636 square-root'</span><span class="p">)</span>
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec'</span><span class="p">)</span>
|
||||
<span class="n">define</span><span class="p">(</span><span class="s1">'sqrt == gsra within'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="output_wrapper">
|
||||
<div class="output">
|
||||
|
||||
|
||||
<div class="output_area">
|
||||
|
||||
<div class="prompt"></div>
|
||||
|
||||
|
||||
<div class="output_subarea output_stream output_stdout output_text">
|
||||
<pre>2212475.6192184356
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [10]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="mf">2212475.6192184356</span> <span class="o">*</span> <span class="mf">2212475.6192184356</span>
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
|
@ -12104,13 +12123,44 @@ n a'' e ε K
|
|||
|
||||
<div class="output_area">
|
||||
|
||||
<div class="prompt output_prompt">Out[10]:</div>
|
||||
<div class="prompt"></div>
|
||||
|
||||
|
||||
<div class="output_subarea output_stream output_stdout output_text">
|
||||
<pre>4.795831523312719
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [11]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="mf">4.795831523312719</span><span class="o">**</span><span class="mi">2</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="output_wrapper">
|
||||
<div class="output">
|
||||
|
||||
|
||||
<div class="output_area">
|
||||
|
||||
<div class="prompt output_prompt">Out[11]:</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="output_text output_subarea output_execute_result">
|
||||
<pre>4895048365636.0</pre>
|
||||
<pre>22.999999999999996</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# [Newton's method](https://en.wikipedia.org/wiki/Newton%27s_method)"
|
||||
"# [Newton's method](https://en.wikipedia.org/wiki/Newton%27s_method)\n",
|
||||
"Let's use the Newton-Raphson method for finding the root of an equation to write a function that can compute the square root of a number.\n",
|
||||
"\n",
|
||||
"Cf. [\"Why Functional Programming Matters\" by John Hughes](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -20,13 +23,23 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Cf. [\"Why Functional Programming Matters\" by John Hughes](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf)"
|
||||
"## A Generator for Approximations\n",
|
||||
"\n",
|
||||
"To make a generator that generates successive approximations let’s start by assuming an initial approximation and then derive the function that computes the next approximation:\n",
|
||||
"\n",
|
||||
" a F\n",
|
||||
" ---------\n",
|
||||
" a'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### A Function to Compute the Next Approximation\n",
|
||||
"\n",
|
||||
"This is the equation for computing the next approximate value of the square root:\n",
|
||||
"\n",
|
||||
"$a_{i+1} = \\frac{(a_i+\\frac{n}{a_i})}{2}$"
|
||||
]
|
||||
},
|
||||
|
|
@ -34,21 +47,41 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Let's define a function that computes the above equation:\n",
|
||||
"\n",
|
||||
" n a Q\n",
|
||||
" ---------------\n",
|
||||
" (a+n/a)/2\n",
|
||||
"\n",
|
||||
" n a tuck / + 2 /\n",
|
||||
" a n over / + 2 /\n",
|
||||
" a n a / + 2 /\n",
|
||||
" a n/a + 2 /\n",
|
||||
" a+n/a 2 /\n",
|
||||
" (a+n/a)/2\n",
|
||||
"\n",
|
||||
"We want it to leave n but replace a, so we execute it with `unary`:\n",
|
||||
"The function we want has the argument `n` in it:\n",
|
||||
"\n",
|
||||
" Q == [tuck / + 2 /] unary"
|
||||
" F == n over / + 2 /"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Make it into a Generator\n",
|
||||
"\n",
|
||||
"Our generator would be created by:\n",
|
||||
"\n",
|
||||
" a [dup F] make_generator\n",
|
||||
"\n",
|
||||
"With n as part of the function F, but n is the input to the sqrt function we’re writing. If we let 1 be the initial approximation:\n",
|
||||
"\n",
|
||||
" 1 n 1 / + 2 /\n",
|
||||
" 1 n/1 + 2 /\n",
|
||||
" 1 n + 2 /\n",
|
||||
" n+1 2 /\n",
|
||||
" (n+1)/2\n",
|
||||
"\n",
|
||||
"The generator can be written as:\n",
|
||||
"\n",
|
||||
" 23 1 swap [over / + 2 /] cons [dup] swoncat make_generator\n",
|
||||
" 1 23 [over / + 2 /] cons [dup] swoncat make_generator\n",
|
||||
" 1 [23 over / + 2 /] [dup] swoncat make_generator\n",
|
||||
" 1 [dup 23 over / + 2 /] make_generator"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -57,125 +90,122 @@
|
|||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"define('Q == [tuck / + 2 /] unary')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"And a function to compute the error:\n",
|
||||
"\n",
|
||||
" n a sqr - abs\n",
|
||||
" |n-a**2|\n",
|
||||
"\n",
|
||||
"This should be `nullary` so as to leave both n and a on the stack below the error.\n",
|
||||
"\n",
|
||||
" err == [sqr - abs] nullary"
|
||||
"define('codireco == cons dip rest cons')\n",
|
||||
"define('make_generator == [codireco] ccons')\n",
|
||||
"define('ccons == cons cons')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"define('err == [sqr - abs] nullary')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now we can define a recursive program that expects a number `n`, an initial estimate `a`, and an epsilon value `ε`, and that leaves on the stack the square root of `n` to within the precision of the epsilon value. (Later on we'll refine it to generate the initial estimate and hard-code an epsilon value.)\n",
|
||||
"\n",
|
||||
" n a ε square-root\n",
|
||||
" -----------------\n",
|
||||
" √n\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"If we apply the two functions `Q` and `err` defined above we get the next approximation and the error on the stack below the epsilon.\n",
|
||||
"\n",
|
||||
" n a ε [Q err] dip\n",
|
||||
" n a Q err ε \n",
|
||||
" n a' err ε \n",
|
||||
" n a' e ε\n",
|
||||
"\n",
|
||||
"Let's define the recursive function from here. Start with `ifte`; the predicate and the base case behavior are obvious:\n",
|
||||
"\n",
|
||||
" n a' e ε [<] [popop popd] [J] ifte\n",
|
||||
"\n",
|
||||
"Base-case\n",
|
||||
"\n",
|
||||
" n a' e ε popop popd\n",
|
||||
" n a' popd\n",
|
||||
" a'\n",
|
||||
"\n",
|
||||
"The recursive branch is pretty easy. Discard the error and recur.\n",
|
||||
"\n",
|
||||
" w/ K == [<] [popop popd] [J] ifte\n",
|
||||
"\n",
|
||||
" n a' e ε J\n",
|
||||
" n a' e ε popd [Q err] dip [K] i\n",
|
||||
" n a' ε [Q err] dip [K] i\n",
|
||||
" n a' Q err ε [K] i\n",
|
||||
" n a'' e ε K\n",
|
||||
"\n",
|
||||
"This fragment alone is pretty useful."
|
||||
"define('gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"define('K == [<] [popop popd] [popd [Q err] dip] primrec')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"5.000000232305737\n"
|
||||
"[1 [dup 23 over / + 2 /] codireco]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J('25 10 0.001 dup K')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"5.000000000000005\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J('25 10 0.000001 dup K')"
|
||||
"J('23 gsra')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So now all we need is a way to generate an initial approximation and an epsilon value:\n",
|
||||
"Let's drive the generator a few time (with the `x` combinator) and square the approximation to see how well it works..."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"23.0000000001585\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J('23 gsra 6 [x popd] times first sqr')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Finding Consecutive Approximations within a Tolerance\n",
|
||||
"\n",
|
||||
" square-root == dup 3 / 0.000001 dup K"
|
||||
"\n",
|
||||
"> The remainder of a square root finder is a function _within_, which takes a tolerance and a list of approximations and looks down the list for two successive approximations that differ by no more than the given tolerance.\n",
|
||||
"\n",
|
||||
"From [\"Why Functional Programming Matters\" by John Hughes](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf)\n",
|
||||
"\n",
|
||||
"(And note that by “list” he means a lazily-evaluated list.)\n",
|
||||
"\n",
|
||||
"Using the _output_ `[a G]` of the above generator for square root approximations, and further assuming that the first term a has been generated already and epsilon ε is handy on the stack...\n",
|
||||
"\n",
|
||||
" a [b G] ε within\n",
|
||||
" ---------------------- a b - abs ε <=\n",
|
||||
" b\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" a [b G] ε within\n",
|
||||
" ---------------------- a b - abs ε >\n",
|
||||
" b [c G] ε within\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Predicate\n",
|
||||
"\n",
|
||||
" a [b G] ε [first - abs] dip <=\n",
|
||||
" a [b G] first - abs ε <=\n",
|
||||
" a b - abs ε <=\n",
|
||||
" a-b abs ε <=\n",
|
||||
" abs(a-b) ε <=\n",
|
||||
" (abs(a-b)<=ε)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"define('_within_P == [first - abs] dip <=')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Base-Case\n",
|
||||
"\n",
|
||||
" a [b G] ε roll< popop first\n",
|
||||
" [b G] ε a popop first\n",
|
||||
" [b G] first\n",
|
||||
" b"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -184,61 +214,103 @@
|
|||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"define('square-root == dup 3 / 0.000001 dup K')"
|
||||
"define('_within_B == roll< popop first')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Recur\n",
|
||||
"\n",
|
||||
" a [b G] ε R0 [within] R1\n",
|
||||
"\n",
|
||||
"1. Discard a.\n",
|
||||
"2. Use x combinator to generate next term from G.\n",
|
||||
"3. Run within with `i` (it is a `primrec` function.)\n",
|
||||
"\n",
|
||||
"Pretty straightforward:\n",
|
||||
"\n",
|
||||
" a [b G] ε R0 [within] R1\n",
|
||||
" a [b G] ε [popd x] dip [within] i\n",
|
||||
" a [b G] popd x ε [within] i\n",
|
||||
" [b G] x ε [within] i\n",
|
||||
" b [c G] ε [within] i\n",
|
||||
" b [c G] ε within\n",
|
||||
"\n",
|
||||
" b [c G] ε within"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"6.000000000000007\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"J('36 square-root')"
|
||||
"define('_within_R == [popd x] dip')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Setting up\n",
|
||||
"\n",
|
||||
"The recursive function we have defined so far needs a slight preamble: `x` to prime the generator and the epsilon value to use:\n",
|
||||
"\n",
|
||||
" [a G] x ε ...\n",
|
||||
" a [b G] ε ..."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2212475.6192184356\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"J('4895048365636 square-root')"
|
||||
"define('within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec')\n",
|
||||
"define('sqrt == gsra within')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"4.795831523312719\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J('23 sqrt')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"4895048365636.0"
|
||||
"22.999999999999996"
|
||||
]
|
||||
},
|
||||
"execution_count": 10,
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"2212475.6192184356 * 2212475.6192184356"
|
||||
"4.795831523312719**2"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,140 +1,190 @@
|
|||
|
||||
# [Newton's method](https://en.wikipedia.org/wiki/Newton%27s_method)
|
||||
Let's use the Newton-Raphson method for finding the root of an equation to write a function that can compute the square root of a number.
|
||||
|
||||
Cf. ["Why Functional Programming Matters" by John Hughes](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf)
|
||||
|
||||
|
||||
```python
|
||||
from notebook_preamble import J, V, define
|
||||
```
|
||||
|
||||
Cf. ["Why Functional Programming Matters" by John Hughes](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf)
|
||||
## A Generator for Approximations
|
||||
|
||||
To make a generator that generates successive approximations let’s start by assuming an initial approximation and then derive the function that computes the next approximation:
|
||||
|
||||
a F
|
||||
---------
|
||||
a'
|
||||
|
||||
### A Function to Compute the Next Approximation
|
||||
|
||||
This is the equation for computing the next approximate value of the square root:
|
||||
|
||||
$a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}$
|
||||
|
||||
Let's define a function that computes the above equation:
|
||||
|
||||
n a Q
|
||||
---------------
|
||||
(a+n/a)/2
|
||||
|
||||
n a tuck / + 2 /
|
||||
a n over / + 2 /
|
||||
a n a / + 2 /
|
||||
a n/a + 2 /
|
||||
a+n/a 2 /
|
||||
(a+n/a)/2
|
||||
|
||||
We want it to leave n but replace a, so we execute it with `unary`:
|
||||
The function we want has the argument `n` in it:
|
||||
|
||||
Q == [tuck / + 2 /] unary
|
||||
F == n over / + 2 /
|
||||
|
||||
### Make it into a Generator
|
||||
|
||||
Our generator would be created by:
|
||||
|
||||
a [dup F] make_generator
|
||||
|
||||
With n as part of the function F, but n is the input to the sqrt function we’re writing. If we let 1 be the initial approximation:
|
||||
|
||||
1 n 1 / + 2 /
|
||||
1 n/1 + 2 /
|
||||
1 n + 2 /
|
||||
n+1 2 /
|
||||
(n+1)/2
|
||||
|
||||
The generator can be written as:
|
||||
|
||||
23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 23 [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 [23 over / + 2 /] [dup] swoncat make_generator
|
||||
1 [dup 23 over / + 2 /] make_generator
|
||||
|
||||
|
||||
```python
|
||||
define('Q == [tuck / + 2 /] unary')
|
||||
```
|
||||
|
||||
And a function to compute the error:
|
||||
|
||||
n a sqr - abs
|
||||
|n-a**2|
|
||||
|
||||
This should be `nullary` so as to leave both n and a on the stack below the error.
|
||||
|
||||
err == [sqr - abs] nullary
|
||||
|
||||
|
||||
```python
|
||||
define('err == [sqr - abs] nullary')
|
||||
```
|
||||
|
||||
Now we can define a recursive program that expects a number `n`, an initial estimate `a`, and an epsilon value `ε`, and that leaves on the stack the square root of `n` to within the precision of the epsilon value. (Later on we'll refine it to generate the initial estimate and hard-code an epsilon value.)
|
||||
|
||||
n a ε square-root
|
||||
-----------------
|
||||
√n
|
||||
|
||||
|
||||
If we apply the two functions `Q` and `err` defined above we get the next approximation and the error on the stack below the epsilon.
|
||||
|
||||
n a ε [Q err] dip
|
||||
n a Q err ε
|
||||
n a' err ε
|
||||
n a' e ε
|
||||
|
||||
Let's define the recursive function from here. Start with `ifte`; the predicate and the base case behavior are obvious:
|
||||
|
||||
n a' e ε [<] [popop popd] [J] ifte
|
||||
|
||||
Base-case
|
||||
|
||||
n a' e ε popop popd
|
||||
n a' popd
|
||||
a'
|
||||
|
||||
The recursive branch is pretty easy. Discard the error and recur.
|
||||
|
||||
w/ K == [<] [popop popd] [J] ifte
|
||||
|
||||
n a' e ε J
|
||||
n a' e ε popd [Q err] dip [K] i
|
||||
n a' ε [Q err] dip [K] i
|
||||
n a' Q err ε [K] i
|
||||
n a'' e ε K
|
||||
|
||||
This fragment alone is pretty useful.
|
||||
|
||||
|
||||
```python
|
||||
define('K == [<] [popop popd] [popd [Q err] dip] primrec')
|
||||
define('codireco == cons dip rest cons')
|
||||
define('make_generator == [codireco] ccons')
|
||||
define('ccons == cons cons')
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
J('25 10 0.001 dup K')
|
||||
```
|
||||
|
||||
5.000000232305737
|
||||
|
||||
|
||||
|
||||
```python
|
||||
J('25 10 0.000001 dup K')
|
||||
```
|
||||
|
||||
5.000000000000005
|
||||
|
||||
|
||||
So now all we need is a way to generate an initial approximation and an epsilon value:
|
||||
|
||||
square-root == dup 3 / 0.000001 dup K
|
||||
|
||||
|
||||
```python
|
||||
define('square-root == dup 3 / 0.000001 dup K')
|
||||
define('gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator')
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
J('36 square-root')
|
||||
J('23 gsra')
|
||||
```
|
||||
|
||||
6.000000000000007
|
||||
[1 [dup 23 over / + 2 /] codireco]
|
||||
|
||||
|
||||
Let's drive the generator a few time (with the `x` combinator) and square the approximation to see how well it works...
|
||||
|
||||
|
||||
```python
|
||||
J('23 gsra 6 [x popd] times first sqr')
|
||||
```
|
||||
|
||||
23.0000000001585
|
||||
|
||||
|
||||
## Finding Consecutive Approximations within a Tolerance
|
||||
|
||||
|
||||
> The remainder of a square root finder is a function _within_, which takes a tolerance and a list of approximations and looks down the list for two successive approximations that differ by no more than the given tolerance.
|
||||
|
||||
From ["Why Functional Programming Matters" by John Hughes](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf)
|
||||
|
||||
(And note that by “list” he means a lazily-evaluated list.)
|
||||
|
||||
Using the _output_ `[a G]` of the above generator for square root approximations, and further assuming that the first term a has been generated already and epsilon ε is handy on the stack...
|
||||
|
||||
a [b G] ε within
|
||||
---------------------- a b - abs ε <=
|
||||
b
|
||||
|
||||
|
||||
a [b G] ε within
|
||||
---------------------- a b - abs ε >
|
||||
b [c G] ε within
|
||||
|
||||
|
||||
|
||||
### Predicate
|
||||
|
||||
a [b G] ε [first - abs] dip <=
|
||||
a [b G] first - abs ε <=
|
||||
a b - abs ε <=
|
||||
a-b abs ε <=
|
||||
abs(a-b) ε <=
|
||||
(abs(a-b)<=ε)
|
||||
|
||||
|
||||
```python
|
||||
define('_within_P == [first - abs] dip <=')
|
||||
```
|
||||
|
||||
### Base-Case
|
||||
|
||||
a [b G] ε roll< popop first
|
||||
[b G] ε a popop first
|
||||
[b G] first
|
||||
b
|
||||
|
||||
|
||||
```python
|
||||
define('_within_B == roll< popop first')
|
||||
```
|
||||
|
||||
### Recur
|
||||
|
||||
a [b G] ε R0 [within] R1
|
||||
|
||||
1. Discard a.
|
||||
2. Use x combinator to generate next term from G.
|
||||
3. Run within with `i` (it is a `primrec` function.)
|
||||
|
||||
Pretty straightforward:
|
||||
|
||||
a [b G] ε R0 [within] R1
|
||||
a [b G] ε [popd x] dip [within] i
|
||||
a [b G] popd x ε [within] i
|
||||
[b G] x ε [within] i
|
||||
b [c G] ε [within] i
|
||||
b [c G] ε within
|
||||
|
||||
b [c G] ε within
|
||||
|
||||
|
||||
```python
|
||||
define('_within_R == [popd x] dip')
|
||||
```
|
||||
|
||||
### Setting up
|
||||
|
||||
The recursive function we have defined so far needs a slight preamble: `x` to prime the generator and the epsilon value to use:
|
||||
|
||||
[a G] x ε ...
|
||||
a [b G] ε ...
|
||||
|
||||
|
||||
```python
|
||||
define('within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec')
|
||||
define('sqrt == gsra within')
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
J('23 sqrt')
|
||||
```
|
||||
|
||||
4.795831523312719
|
||||
|
||||
|
||||
|
||||
```python
|
||||
J('4895048365636 square-root')
|
||||
```
|
||||
|
||||
2212475.6192184356
|
||||
|
||||
|
||||
|
||||
```python
|
||||
2212475.6192184356 * 2212475.6192184356
|
||||
4.795831523312719**2
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
4895048365636.0
|
||||
22.999999999999996
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,172 +2,234 @@
|
|||
`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
|
||||
=====================================================================
|
||||
|
||||
Let's use the Newton-Raphson method for finding the root of an equation
|
||||
to write a function that can compute the square root of a number.
|
||||
|
||||
Cf. `"Why Functional Programming Matters" by John
|
||||
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
from notebook_preamble import J, V, define
|
||||
|
||||
Cf. `"Why Functional Programming Matters" by John
|
||||
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
|
||||
A Generator for Approximations
|
||||
------------------------------
|
||||
|
||||
:math:`a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}`
|
||||
|
||||
Let's define a function that computes the above equation:
|
||||
To make a generator that generates successive approximations let’s start
|
||||
by assuming an initial approximation and then derive the function that
|
||||
computes the next approximation:
|
||||
|
||||
::
|
||||
|
||||
n a Q
|
||||
---------------
|
||||
(a+n/a)/2
|
||||
a F
|
||||
---------
|
||||
a'
|
||||
|
||||
n a tuck / + 2 /
|
||||
A Function to Compute the Next Approximation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is the equation for computing the next approximate value of the
|
||||
square root:
|
||||
|
||||
:math:`a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}`
|
||||
|
||||
::
|
||||
|
||||
a n over / + 2 /
|
||||
a n a / + 2 /
|
||||
a n/a + 2 /
|
||||
a+n/a 2 /
|
||||
(a+n/a)/2
|
||||
|
||||
We want it to leave n but replace a, so we execute it with ``unary``:
|
||||
The function we want has the argument ``n`` in it:
|
||||
|
||||
::
|
||||
|
||||
Q == [tuck / + 2 /] unary
|
||||
F == n over / + 2 /
|
||||
|
||||
Make it into a Generator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Our generator would be created by:
|
||||
|
||||
::
|
||||
|
||||
a [dup F] make_generator
|
||||
|
||||
With n as part of the function F, but n is the input to the sqrt
|
||||
function we’re writing. If we let 1 be the initial approximation:
|
||||
|
||||
::
|
||||
|
||||
1 n 1 / + 2 /
|
||||
1 n/1 + 2 /
|
||||
1 n + 2 /
|
||||
n+1 2 /
|
||||
(n+1)/2
|
||||
|
||||
The generator can be written as:
|
||||
|
||||
::
|
||||
|
||||
23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 23 [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 [23 over / + 2 /] [dup] swoncat make_generator
|
||||
1 [dup 23 over / + 2 /] make_generator
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('Q == [tuck / + 2 /] unary')
|
||||
|
||||
And a function to compute the error:
|
||||
|
||||
::
|
||||
|
||||
n a sqr - abs
|
||||
|n-a**2|
|
||||
|
||||
This should be ``nullary`` so as to leave both n and a on the stack
|
||||
below the error.
|
||||
|
||||
::
|
||||
|
||||
err == [sqr - abs] nullary
|
||||
define('codireco == cons dip rest cons')
|
||||
define('make_generator == [codireco] ccons')
|
||||
define('ccons == cons cons')
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('err == [sqr - abs] nullary')
|
||||
|
||||
Now we can define a recursive program that expects a number ``n``, an
|
||||
initial estimate ``a``, and an epsilon value ``ε``, and that leaves on
|
||||
the stack the square root of ``n`` to within the precision of the
|
||||
epsilon value. (Later on we'll refine it to generate the initial
|
||||
estimate and hard-code an epsilon value.)
|
||||
|
||||
::
|
||||
|
||||
n a ε square-root
|
||||
-----------------
|
||||
√n
|
||||
|
||||
If we apply the two functions ``Q`` and ``err`` defined above we get the
|
||||
next approximation and the error on the stack below the epsilon.
|
||||
|
||||
::
|
||||
|
||||
n a ε [Q err] dip
|
||||
n a Q err ε
|
||||
n a' err ε
|
||||
n a' e ε
|
||||
|
||||
Let's define the recursive function from here. Start with ``ifte``; the
|
||||
predicate and the base case behavior are obvious:
|
||||
|
||||
::
|
||||
|
||||
n a' e ε [<] [popop popd] [J] ifte
|
||||
|
||||
Base-case
|
||||
|
||||
::
|
||||
|
||||
n a' e ε popop popd
|
||||
n a' popd
|
||||
a'
|
||||
|
||||
The recursive branch is pretty easy. Discard the error and recur.
|
||||
|
||||
::
|
||||
|
||||
w/ K == [<] [popop popd] [J] ifte
|
||||
|
||||
n a' e ε J
|
||||
n a' e ε popd [Q err] dip [K] i
|
||||
n a' ε [Q err] dip [K] i
|
||||
n a' Q err ε [K] i
|
||||
n a'' e ε K
|
||||
|
||||
This fragment alone is pretty useful.
|
||||
define('gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator')
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('K == [<] [popop popd] [popd [Q err] dip] primrec')
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
J('25 10 0.001 dup K')
|
||||
J('23 gsra')
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
5.000000232305737
|
||||
[1 [dup 23 over / + 2 /] codireco]
|
||||
|
||||
|
||||
Let's drive the generator a few time (with the ``x`` combinator) and
|
||||
square the approximation to see how well it works...
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
J('25 10 0.000001 dup K')
|
||||
J('23 gsra 6 [x popd] times first sqr')
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
5.000000000000005
|
||||
23.0000000001585
|
||||
|
||||
|
||||
So now all we need is a way to generate an initial approximation and an
|
||||
epsilon value:
|
||||
Finding Consecutive Approximations within a Tolerance
|
||||
-----------------------------------------------------
|
||||
|
||||
The remainder of a square root finder is a function *within*, which
|
||||
takes a tolerance and a list of approximations and looks down the
|
||||
list for two successive approximations that differ by no more than
|
||||
the given tolerance.
|
||||
|
||||
From `"Why Functional Programming Matters" by John
|
||||
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
|
||||
|
||||
(And note that by “list” he means a lazily-evaluated list.)
|
||||
|
||||
Using the *output* ``[a G]`` of the above generator for square root
|
||||
approximations, and further assuming that the first term a has been
|
||||
generated already and epsilon ε is handy on the stack...
|
||||
|
||||
::
|
||||
|
||||
square-root == dup 3 / 0.000001 dup K
|
||||
a [b G] ε within
|
||||
---------------------- a b - abs ε <=
|
||||
b
|
||||
|
||||
|
||||
a [b G] ε within
|
||||
---------------------- a b - abs ε >
|
||||
b [c G] ε within
|
||||
|
||||
Predicate
|
||||
~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
a [b G] ε [first - abs] dip <=
|
||||
a [b G] first - abs ε <=
|
||||
a b - abs ε <=
|
||||
a-b abs ε <=
|
||||
abs(a-b) ε <=
|
||||
(abs(a-b)<=ε)
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('square-root == dup 3 / 0.000001 dup K')
|
||||
define('_within_P == [first - abs] dip <=')
|
||||
|
||||
Base-Case
|
||||
~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
a [b G] ε roll< popop first
|
||||
[b G] ε a popop first
|
||||
[b G] first
|
||||
b
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
J('36 square-root')
|
||||
define('_within_B == roll< popop first')
|
||||
|
||||
Recur
|
||||
~~~~~
|
||||
|
||||
::
|
||||
|
||||
a [b G] ε R0 [within] R1
|
||||
|
||||
1. Discard a.
|
||||
2. Use x combinator to generate next term from G.
|
||||
3. Run within with ``i`` (it is a ``primrec`` function.)
|
||||
|
||||
Pretty straightforward:
|
||||
|
||||
::
|
||||
|
||||
a [b G] ε R0 [within] R1
|
||||
a [b G] ε [popd x] dip [within] i
|
||||
a [b G] popd x ε [within] i
|
||||
[b G] x ε [within] i
|
||||
b [c G] ε [within] i
|
||||
b [c G] ε within
|
||||
|
||||
b [c G] ε within
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('_within_R == [popd x] dip')
|
||||
|
||||
Setting up
|
||||
~~~~~~~~~~
|
||||
|
||||
The recursive function we have defined so far needs a slight preamble:
|
||||
``x`` to prime the generator and the epsilon value to use:
|
||||
|
||||
::
|
||||
|
||||
[a G] x ε ...
|
||||
a [b G] ε ...
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec')
|
||||
define('sqrt == gsra within')
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
J('23 sqrt')
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
6.000000000000007
|
||||
4.795831523312719
|
||||
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
J('4895048365636 square-root')
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
2212475.6192184356
|
||||
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
2212475.6192184356 * 2212475.6192184356
|
||||
4.795831523312719**2
|
||||
|
||||
|
||||
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
4895048365636.0
|
||||
22.999999999999996
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11826,11 +11826,21 @@ div#notebook {
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h1 id="Write-a-straightforward-program-with-variable-names.">Write a straightforward program with variable names.<a class="anchor-link" href="#Write-a-straightforward-program-with-variable-names.">¶</a></h1>
|
||||
<h2 id="Write-a-straightforward-program-with-variable-names.">Write a straightforward program with variable names.<a class="anchor-link" href="#Write-a-straightforward-program-with-variable-names.">¶</a></h2>
|
||||
<pre><code>b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
|
||||
</code></pre>
|
||||
<h3 id="Check-it.">Check it.<a class="anchor-link" href="#Check-it.">¶</a></h3>
|
||||
<p>We use <code>cleave</code> to compute the sum and difference and then <code>app2</code> to finish computing both roots using a quoted program <code>[2a truediv]</code> built with <code>cons</code>.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Check-it.">Check it.<a class="anchor-link" href="#Check-it.">¶</a></h3><p>Evaluating by hand:</p>
|
||||
|
||||
<pre><code> b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
-b b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
-b b^2 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
|
|
@ -11842,8 +11852,18 @@ div#notebook {
|
|||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) 2a [truediv] cons app2
|
||||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] app2
|
||||
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||
|
||||
</code></pre>
|
||||
<h3 id="Codicil">Codicil<a class="anchor-link" href="#Codicil">¶</a></h3>
|
||||
<p>(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands to do this sort of thing symbolically. This is part of what is meant by a “categorical” language.)</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Cleanup">Cleanup<a class="anchor-link" href="#Cleanup">¶</a></h3>
|
||||
<pre><code>-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a roll< pop
|
||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a -b pop
|
||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a</code></pre>
|
||||
|
|
@ -11855,7 +11875,7 @@ div#notebook {
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h1 id="Derive-a-definition.">Derive a definition.<a class="anchor-link" href="#Derive-a-definition.">¶</a></h1>
|
||||
<h2 id="Derive-a-definition.">Derive a definition.<a class="anchor-link" href="#Derive-a-definition.">¶</a></h2>
|
||||
<pre><code>b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
|
||||
b [neg] dupdip sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
|
||||
b a c [[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
|
||||
|
|
@ -11913,23 +11933,20 @@ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truedi
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Simplify">Simplify<a class="anchor-link" href="#Simplify">¶</a></h3><p>We can define a <code>pm</code> plus-or-minus function:</p>
|
||||
<h2 id="Simplify">Simplify<a class="anchor-link" href="#Simplify">¶</a></h2><p>We can define a <code>pm</code> plus-or-minus function:</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [4]:</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'pm == [+] [-] cleave popdd'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
|
||||
<pre><code>pm == [+] [-] cleave popdd</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||
</div>
|
||||
|
|
@ -11942,7 +11959,7 @@ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truedi
|
|||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [5]:</div>
|
||||
<div class="prompt input_prompt">In [4]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2'</span><span class="p">)</span>
|
||||
|
|
@ -11955,7 +11972,7 @@ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truedi
|
|||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [6]:</div>
|
||||
<div class="prompt input_prompt">In [5]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 1 1 quadratic'</span><span class="p">)</span>
|
||||
|
|
@ -11988,28 +12005,20 @@ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truedi
|
|||
</div>
|
||||
<div class="inner_cell">
|
||||
<div class="text_cell_render border-box-sizing rendered_html">
|
||||
<h3 id="Define-a-"native"-pm-function.">Define a "native" <code>pm</code> function.<a class="anchor-link" href="#Define-a-"native"-pm-function.">¶</a></h3><p>The definition of <code>pm</code> above is pretty elegant, but the implementation takes a lot of steps relative to what it's accomplishing. Since we are likely to use <code>pm</code> more than once in the future, let's write a primitive in Python and add it to the dictionary.</p>
|
||||
<h3 id="Define-a-"native"-pm-function.">Define a "native" <code>pm</code> function.<a class="anchor-link" href="#Define-a-"native"-pm-function.">¶</a></h3><p>The definition of <code>pm</code> above is pretty elegant, but the implementation takes a lot of steps relative to what it's accomplishing. Since we are likely to use <code>pm</code> more than once in the future, let's write a primitive in Python and add it to the dictionary. (This has been done already.)</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [7]:</div>
|
||||
<div class="prompt input_prompt">In [6]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">SimpleFunctionWrapper</span>
|
||||
<span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span>
|
||||
|
||||
|
||||
<span class="nd">@SimpleFunctionWrapper</span>
|
||||
<span class="k">def</span> <span class="nf">pm</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">pm</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
|
||||
<span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
|
||||
<span class="n">p</span><span class="p">,</span> <span class="n">m</span><span class="p">,</span> <span class="o">=</span> <span class="n">b</span> <span class="o">+</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">-</span> <span class="n">a</span>
|
||||
<span class="k">return</span> <span class="n">m</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="n">D</span><span class="p">[</span><span class="s1">'pm'</span><span class="p">]</span> <span class="o">=</span> <span class="n">pm</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
|
@ -12028,7 +12037,7 @@ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truedi
|
|||
</div>
|
||||
<div class="cell border-box-sizing code_cell rendered">
|
||||
<div class="input">
|
||||
<div class="prompt input_prompt">In [8]:</div>
|
||||
<div class="prompt input_prompt">In [7]:</div>
|
||||
<div class="inner_cell">
|
||||
<div class="input_area">
|
||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'3 1 1 quadratic'</span><span class="p">)</span>
|
||||
|
|
|
|||
|
|
@ -43,10 +43,19 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Write a straightforward program with variable names.\n",
|
||||
"## Write a straightforward program with variable names.\n",
|
||||
"\n",
|
||||
" b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n",
|
||||
"\n",
|
||||
"We use `cleave` to compute the sum and difference and then `app2` to finish computing both roots using a quoted program `[2a truediv]` built with `cons`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Check it.\n",
|
||||
"Evaluating by hand:\n",
|
||||
"\n",
|
||||
" b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n",
|
||||
" -b b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n",
|
||||
|
|
@ -59,7 +68,15 @@
|
|||
" -b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) 2a [truediv] cons app2\n",
|
||||
" -b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] app2\n",
|
||||
" -b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a\n",
|
||||
"### Codicil\n",
|
||||
"\n",
|
||||
"(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands to do this sort of thing symbolically. This is part of what is meant by a “categorical” language.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Cleanup\n",
|
||||
" -b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a roll< pop\n",
|
||||
" -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a -b pop\n",
|
||||
" -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a"
|
||||
|
|
@ -69,7 +86,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Derive a definition.\n",
|
||||
"## Derive a definition.\n",
|
||||
"\n",
|
||||
" b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop\n",
|
||||
" b [neg] dupdip sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop\n",
|
||||
|
|
@ -108,17 +125,15 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Simplify\n",
|
||||
"## Simplify\n",
|
||||
"We can define a `pm` plus-or-minus function:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"define('pm == [+] [-] cleave popdd')"
|
||||
" pm == [+] [-] cleave popdd"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -130,7 +145,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
|
@ -139,7 +154,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
|
|
@ -159,27 +174,19 @@
|
|||
"metadata": {},
|
||||
"source": [
|
||||
"### Define a \"native\" `pm` function.\n",
|
||||
"The definition of `pm` above is pretty elegant, but the implementation takes a lot of steps relative to what it's accomplishing. Since we are likely to use `pm` more than once in the future, let's write a primitive in Python and add it to the dictionary."
|
||||
"The definition of `pm` above is pretty elegant, but the implementation takes a lot of steps relative to what it's accomplishing. Since we are likely to use `pm` more than once in the future, let's write a primitive in Python and add it to the dictionary. (This has been done already.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from joy.library import SimpleFunctionWrapper\n",
|
||||
"from notebook_preamble import D\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"@SimpleFunctionWrapper\n",
|
||||
"def pm(stack):\n",
|
||||
" a, (b, stack) = stack\n",
|
||||
" p, m, = b + a, b - a\n",
|
||||
" return m, (p, stack)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"D['pm'] = pm"
|
||||
" return m, (p, stack)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -191,7 +198,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,10 +14,14 @@ Cf. [jp-quadratic.html](http://www.kevinalbrecht.com/code/joy-mirror/jp-quadrati
|
|||
|
||||
$\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$
|
||||
|
||||
# Write a straightforward program with variable names.
|
||||
## Write a straightforward program with variable names.
|
||||
|
||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
|
||||
We use `cleave` to compute the sum and difference and then `app2` to finish computing both roots using a quoted program `[2a truediv]` built with `cons`.
|
||||
|
||||
### Check it.
|
||||
Evaluating by hand:
|
||||
|
||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
-b b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
|
|
@ -30,12 +34,15 @@ $\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$
|
|||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) 2a [truediv] cons app2
|
||||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] app2
|
||||
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||
### Codicil
|
||||
|
||||
(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands to do this sort of thing symbolically. This is part of what is meant by a “categorical” language.)
|
||||
|
||||
### Cleanup
|
||||
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a roll< pop
|
||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a -b pop
|
||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||
|
||||
# Derive a definition.
|
||||
## Derive a definition.
|
||||
|
||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
|
||||
b [neg] dupdip sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
|
||||
|
|
@ -56,13 +63,10 @@ J('3 1 1 quadratic')
|
|||
-0.3819660112501051 -2.618033988749895
|
||||
|
||||
|
||||
### Simplify
|
||||
## Simplify
|
||||
We can define a `pm` plus-or-minus function:
|
||||
|
||||
|
||||
```python
|
||||
define('pm == [+] [-] cleave popdd')
|
||||
```
|
||||
pm == [+] [-] cleave popdd
|
||||
|
||||
Then `quadratic` becomes:
|
||||
|
||||
|
|
@ -80,22 +84,14 @@ J('3 1 1 quadratic')
|
|||
|
||||
|
||||
### Define a "native" `pm` function.
|
||||
The definition of `pm` above is pretty elegant, but the implementation takes a lot of steps relative to what it's accomplishing. Since we are likely to use `pm` more than once in the future, let's write a primitive in Python and add it to the dictionary.
|
||||
The definition of `pm` above is pretty elegant, but the implementation takes a lot of steps relative to what it's accomplishing. Since we are likely to use `pm` more than once in the future, let's write a primitive in Python and add it to the dictionary. (This has been done already.)
|
||||
|
||||
|
||||
```python
|
||||
from joy.library import SimpleFunctionWrapper
|
||||
from notebook_preamble import D
|
||||
|
||||
|
||||
@SimpleFunctionWrapper
|
||||
def pm(stack):
|
||||
a, (b, stack) = stack
|
||||
p, m, = b + a, b - a
|
||||
return m, (p, stack)
|
||||
|
||||
|
||||
D['pm'] = pm
|
||||
```
|
||||
|
||||
The resulting trace is short enough to fit on a page.
|
||||
|
|
|
|||
|
|
@ -18,15 +18,21 @@ Cf.
|
|||
:math:`\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`
|
||||
|
||||
Write a straightforward program with variable names.
|
||||
====================================================
|
||||
----------------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
|
||||
We use ``cleave`` to compute the sum and difference and then ``app2`` to
|
||||
finish computing both roots using a quoted program ``[2a truediv]``
|
||||
built with ``cons``.
|
||||
|
||||
Check it.
|
||||
~~~~~~~~~
|
||||
|
||||
Evaluating by hand:
|
||||
|
||||
::
|
||||
|
||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
|
|
@ -41,7 +47,11 @@ Check it.
|
|||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] app2
|
||||
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||
|
||||
Codicil
|
||||
(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands
|
||||
to do this sort of thing symbolically. This is part of what is meant by
|
||||
a “categorical” language.)
|
||||
|
||||
Cleanup
|
||||
~~~~~~~
|
||||
|
||||
::
|
||||
|
|
@ -51,7 +61,7 @@ Codicil
|
|||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||
|
||||
Derive a definition.
|
||||
====================
|
||||
--------------------
|
||||
|
||||
::
|
||||
|
||||
|
|
@ -76,13 +86,13 @@ Derive a definition.
|
|||
|
||||
|
||||
Simplify
|
||||
~~~~~~~~
|
||||
--------
|
||||
|
||||
We can define a ``pm`` plus-or-minus function:
|
||||
|
||||
.. code:: ipython2
|
||||
::
|
||||
|
||||
define('pm == [+] [-] cleave popdd')
|
||||
pm == [+] [-] cleave popdd
|
||||
|
||||
Then ``quadratic`` becomes:
|
||||
|
||||
|
|
@ -106,22 +116,15 @@ Define a "native" ``pm`` function.
|
|||
The definition of ``pm`` above is pretty elegant, but the implementation
|
||||
takes a lot of steps relative to what it's accomplishing. Since we are
|
||||
likely to use ``pm`` more than once in the future, let's write a
|
||||
primitive in Python and add it to the dictionary.
|
||||
primitive in Python and add it to the dictionary. (This has been done
|
||||
already.)
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
from joy.library import SimpleFunctionWrapper
|
||||
from notebook_preamble import D
|
||||
|
||||
|
||||
@SimpleFunctionWrapper
|
||||
def pm(stack):
|
||||
a, (b, stack) = stack
|
||||
p, m, = b + a, b - a
|
||||
return m, (p, stack)
|
||||
|
||||
|
||||
D['pm'] = pm
|
||||
|
||||
The resulting trace is short enough to fit on a page.
|
||||
|
||||
|
|
|
|||
|
|
@ -135,9 +135,10 @@ interesting aspects. It’s quite a treasure trove.</p>
|
|||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Replacing.html">Replacing Functions in the Dictionary</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Generator Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Newton-Raphson.html">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Quadratic.html">Quadratic formula</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Categorical.html">Categorical Programming</a></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -34,18 +34,25 @@
|
|||
|
||||
<div class="section" id="quadratic-formula">
|
||||
<h1><a class="reference external" href="https://en.wikipedia.org/wiki/Quadratic_formula">Quadratic formula</a><a class="headerlink" href="#quadratic-formula" title="Permalink to this headline">¶</a></h1>
|
||||
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Quadratic_formula">The Quadratic formula</a></p>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Cf.
|
||||
<a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html">jp-quadratic.html</a></p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="n">b</span> <span class="o">+/-</span> <span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">4</span> <span class="o">*</span> <span class="n">a</span> <span class="o">*</span> <span class="n">c</span><span class="p">)</span>
|
||||
<span class="o">-----------------------------</span>
|
||||
<span class="mi">2</span> <span class="o">*</span> <span class="n">a</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><span class="math notranslate nohighlight">\(\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\)</span></p>
|
||||
<p>In
|
||||
<a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html">jp-quadratic.html</a>
|
||||
a Joy function for the Quadratic formula is derived (along with one of my favorite combinators <code class="docutils literal notranslate"><span class="pre">[i]</span> <span class="pre">map</span></code>,
|
||||
which I like to call <code class="docutils literal notranslate"><span class="pre">pam</span></code>) starting with a version written in Scheme. Here we investigate a different approach.</p>
|
||||
<div class="section" id="write-a-program-with-variable-names">
|
||||
<h2>Write a program with variable names.<a class="headerlink" href="#write-a-program-with-variable-names" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="section" id="write-a-straightforward-program-with-variable-names">
|
||||
<h2>Write a straightforward program with variable names.<a class="headerlink" href="#write-a-straightforward-program-with-variable-names" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="n">neg</span> <span class="n">b</span> <span class="n">sqr</span> <span class="mi">4</span> <span class="n">a</span> <span class="n">c</span> <span class="o">*</span> <span class="o">*</span> <span class="o">-</span> <span class="n">sqrt</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="p">]</span> <span class="n">cleave</span> <span class="n">a</span> <span class="mi">2</span> <span class="o">*</span> <span class="p">[</span><span class="n">truediv</span><span class="p">]</span> <span class="n">cons</span> <span class="n">app2</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>We use <code class="docutils literal notranslate"><span class="pre">cleave</span></code> to compute the sum and difference (“plus-or-minus”) and then <code class="docutils literal notranslate"><span class="pre">app2</span></code> to finish computing both roots using a quoted program <code class="docutils literal notranslate"><span class="pre">[2a</span> <span class="pre">truediv]</span></code> built with <code class="docutils literal notranslate"><span class="pre">cons</span></code>.</p>
|
||||
<p>We use <code class="docutils literal notranslate"><span class="pre">cleave</span></code> to compute the sum and difference and then <code class="docutils literal notranslate"><span class="pre">app2</span></code> to
|
||||
finish computing both roots using a quoted program <code class="docutils literal notranslate"><span class="pre">[2a</span> <span class="pre">truediv]</span></code>
|
||||
built with <code class="docutils literal notranslate"><span class="pre">cons</span></code>.</p>
|
||||
<div class="section" id="check-it">
|
||||
<h3>Check it.<a class="headerlink" href="#check-it" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Evaluating by hand:</p>
|
||||
|
|
@ -62,12 +69,14 @@ which I like to call <code class="docutils literal notranslate"><span class="pre
|
|||
<span class="o">-</span><span class="n">b</span> <span class="o">-</span><span class="n">b</span><span class="o">+</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="o">-</span><span class="n">b</span><span class="o">-</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands to do this sort of thing symbolically. This is part of what is meant by a “categorical” language.)</p>
|
||||
<p>(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands
|
||||
to do this sort of thing symbolically. This is part of what is meant by
|
||||
a “categorical” language.)</p>
|
||||
</div>
|
||||
<div class="section" id="cleanup">
|
||||
<h3>Cleanup<a class="headerlink" href="#cleanup" title="Permalink to this headline">¶</a></h3>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="n">b</span> <span class="o">-</span><span class="n">b</span><span class="o">+</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="o">-</span><span class="n">b</span><span class="o">-</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="n">roll</span><span class="o"><</span> <span class="n">pop</span>
|
||||
<span class="o">-</span><span class="n">b</span><span class="o">+</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="o">-</span><span class="n">b</span><span class="o">-</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="o">-</span><span class="n">b</span> <span class="n">pop</span>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="n">b</span> <span class="o">-</span><span class="n">b</span><span class="o">+</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="o">-</span><span class="n">b</span><span class="o">-</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="n">roll</span><span class="o"><</span> <span class="n">pop</span>
|
||||
<span class="o">-</span><span class="n">b</span><span class="o">+</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="o">-</span><span class="n">b</span><span class="o">-</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="o">-</span><span class="n">b</span> <span class="n">pop</span>
|
||||
<span class="o">-</span><span class="n">b</span><span class="o">+</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span> <span class="o">-</span><span class="n">b</span><span class="o">-</span><span class="n">sqrt</span><span class="p">(</span><span class="n">b</span><span class="o">^</span><span class="mi">2</span><span class="o">-</span><span class="mi">4</span><span class="n">ac</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="n">a</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -82,9 +91,6 @@ which I like to call <code class="docutils literal notranslate"><span class="pre
|
|||
<span class="n">b</span> <span class="n">a</span> <span class="n">c</span> <span class="n">over</span> <span class="p">[[[</span><span class="n">neg</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">sqr</span> <span class="mi">4</span><span class="p">]</span> <span class="n">dipd</span> <span class="o">*</span> <span class="o">*</span> <span class="o">-</span> <span class="n">sqrt</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="p">]</span> <span class="n">cleave</span><span class="p">]</span> <span class="n">dip</span> <span class="mi">2</span> <span class="o">*</span> <span class="p">[</span><span class="n">truediv</span><span class="p">]</span> <span class="n">cons</span> <span class="n">app2</span> <span class="n">roll</span><span class="o"><</span> <span class="n">pop</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -94,10 +100,11 @@ which I like to call <code class="docutils literal notranslate"><span class="pre
|
|||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mf">0.3819660112501051</span> <span class="o">-</span><span class="mf">2.618033988749895</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="simplify">
|
||||
<h3>Simplify<a class="headerlink" href="#simplify" title="Permalink to this headline">¶</a></h3>
|
||||
<h2>Simplify<a class="headerlink" href="#simplify" title="Permalink to this headline">¶</a></h2>
|
||||
<p>We can define a <code class="docutils literal notranslate"><span class="pre">pm</span></code> plus-or-minus function:</p>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'pm == [+] [-] cleave popdd'</span><span class="p">)</span>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pm</span> <span class="o">==</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="p">]</span> <span class="n">cleave</span> <span class="n">popdd</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Then <code class="docutils literal notranslate"><span class="pre">quadratic</span></code> becomes:</p>
|
||||
|
|
@ -110,25 +117,17 @@ which I like to call <code class="docutils literal notranslate"><span class="pre
|
|||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mf">0.3819660112501051</span> <span class="o">-</span><span class="mf">2.618033988749895</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="define-a-native-pm-function">
|
||||
<h3>Define a “native” <code class="docutils literal notranslate"><span class="pre">pm</span></code> function.<a class="headerlink" href="#define-a-native-pm-function" title="Permalink to this headline">¶</a></h3>
|
||||
<p>The definition of <code class="docutils literal notranslate"><span class="pre">pm</span></code> above is pretty elegant, but the implementation
|
||||
takes a lot of steps relative to what it’s accomplishing. Since we are
|
||||
likely to use <code class="docutils literal notranslate"><span class="pre">pm</span></code> more than once in the future, let’s write a
|
||||
primitive in Python and add it to the dictionary.</p>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="k">import</span> <span class="n">SimpleFunctionWrapper</span>
|
||||
<span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span>
|
||||
|
||||
|
||||
<span class="nd">@SimpleFunctionWrapper</span>
|
||||
<span class="k">def</span> <span class="nf">pm</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
|
||||
primitive in Python and add it to the dictionary. (This has been done
|
||||
already.)</p>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">pm</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
|
||||
<span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
|
||||
<span class="n">p</span><span class="p">,</span> <span class="n">m</span><span class="p">,</span> <span class="o">=</span> <span class="n">b</span> <span class="o">+</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">-</span> <span class="n">a</span>
|
||||
<span class="k">return</span> <span class="n">m</span><span class="p">,</span> <span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="n">D</span><span class="p">[</span><span class="s1">'pm'</span><span class="p">]</span> <span class="o">=</span> <span class="n">pm</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The resulting trace is short enough to fit on a page.</p>
|
||||
|
|
@ -195,13 +194,13 @@ primitive in Python and add it to the dictionary.</p>
|
|||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Quadratic formula</a><ul>
|
||||
<li><a class="reference internal" href="#write-a-program-with-variable-names">Write a program with variable names.</a><ul>
|
||||
<li><a class="reference internal" href="#write-a-straightforward-program-with-variable-names">Write a straightforward program with variable names.</a><ul>
|
||||
<li><a class="reference internal" href="#check-it">Check it.</a></li>
|
||||
<li><a class="reference internal" href="#cleanup">Cleanup</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#derive-a-definition">Derive a definition.</a><ul>
|
||||
<li><a class="reference internal" href="#simplify">Simplify</a></li>
|
||||
<li><a class="reference internal" href="#derive-a-definition">Derive a definition.</a></li>
|
||||
<li><a class="reference internal" href="#simplify">Simplify</a><ul>
|
||||
<li><a class="reference internal" href="#define-a-native-pm-function">Define a “native” <code class="docutils literal notranslate"><span class="pre">pm</span></code> function.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Preamble — Thun 0.2.0 documentation</title>
|
||||
<title>Traversing Datastructures with Zippers — Thun 0.2.0 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script type="text/javascript" src="../_static/documentation_options.js"></script>
|
||||
|
|
@ -30,15 +30,15 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<p>This notebook is about using the “zipper” with joy datastructures. See
|
||||
<div class="section" id="traversing-datastructures-with-zippers">
|
||||
<h1>Traversing Datastructures with Zippers<a class="headerlink" href="#traversing-datastructures-with-zippers" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This notebook is about using the “zipper” with joy datastructures. See
|
||||
the <a class="reference external" href="https://en.wikipedia.org/wiki/Zipper_%28data_structure%29">Zipper wikipedia
|
||||
entry</a> or
|
||||
the original paper: <a class="reference external" href="https://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf">“FUNCTIONAL PEARL The Zipper” by Gérard
|
||||
Huet</a></p>
|
||||
<p>Given a datastructure on the stack we can navigate through it, modify
|
||||
it, and rebuild it using the “zipper” technique.</p>
|
||||
<div class="section" id="preamble">
|
||||
<h1>Preamble<a class="headerlink" href="#preamble" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -309,7 +309,7 @@ i d i d i d d Bingo!
|
|||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Preamble</a><ul>
|
||||
<li><a class="reference internal" href="#">Traversing Datastructures with Zippers</a><ul>
|
||||
<li><a class="reference internal" href="#trees">Trees</a></li>
|
||||
<li><a class="reference internal" href="#zipper-in-joy">Zipper in Joy</a></li>
|
||||
<li><a class="reference internal" href="#dip-and-infra"><code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code></a></li>
|
||||
|
|
|
|||
|
|
@ -73,15 +73,15 @@
|
|||
<li class="toctree-l2"><a class="reference internal" href="Treestep.html#putting-it-together">Putting it together</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Generator Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator Programs.html#direco"><code class="docutils literal notranslate"><span class="pre">direco</span></code></a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator Programs.html#making-generators">Making Generators</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator Programs.html#generating-multiples-of-three-and-five">Generating Multiples of Three and Five</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator Programs.html#project-euler-problem-one">Project Euler Problem One</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator Programs.html#a-generator-for-the-fibonacci-sequence">A generator for the Fibonacci Sequence.</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator Programs.html#project-euler-problem-two">Project Euler Problem Two</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator Programs.html#how-to-compile-these">How to compile these?</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator Programs.html#an-interesting-variation">An Interesting Variation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html#direco"><code class="docutils literal notranslate"><span class="pre">direco</span></code></a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html#making-generators">Making Generators</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html#generating-multiples-of-three-and-five">Generating Multiples of Three and Five</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html#project-euler-problem-one">Project Euler Problem One</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html#a-generator-for-the-fibonacci-sequence">A generator for the Fibonacci Sequence.</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html#project-euler-problem-two">Project Euler Problem Two</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html#how-to-compile-these">How to compile these?</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html#an-interesting-variation">An Interesting Variation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a><ul>
|
||||
|
|
@ -91,8 +91,18 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Quadratic.html">Quadratic formula</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html#write-a-program-with-variable-names">Write a program with variable names.</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html#write-a-straightforward-program-with-variable-names">Write a straightforward program with variable names.</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html#derive-a-definition">Derive a definition.</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html#simplify">Simplify</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html#trees">Trees</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html#zipper-in-joy">Zipper in Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html#dip-and-infra"><code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code></a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html#z"><code class="docutils literal notranslate"><span class="pre">Z</span></code></a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html#addressing">Addressing</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html#determining-the-right-path-for-an-item-in-a-tree">Determining the right “path” for an item in a tree.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -208,9 +208,9 @@ with the ``x`` combinator.
|
|||
Generating Multiples of Three and Five
|
||||
--------------------------------------
|
||||
|
||||
Look at the treatment of the Project Euler Problem One in `Developing a
|
||||
Program.ipynb <./Developing%20a%20Program.ipynb>`__ and you'll see that
|
||||
we might be interested in generating an endless cycle of:
|
||||
Look at the treatment of the Project Euler Problem One in the
|
||||
"Developing a Program" notebook and you'll see that we might be
|
||||
interested in generating an endless cycle of:
|
||||
|
||||
::
|
||||
|
||||
|
|
@ -1,30 +1,39 @@
|
|||
|
||||
***********************************************************************
|
||||
`Quadratic formula <https://en.wikipedia.org/wiki/Quadratic_formula>`__
|
||||
***********************************************************************
|
||||
=======================================================================
|
||||
|
||||
`The Quadratic formula <https://en.wikipedia.org/wiki/Quadratic_formula>`__
|
||||
.. code:: ipython2
|
||||
|
||||
from notebook_preamble import J, V, define
|
||||
|
||||
Cf.
|
||||
`jp-quadratic.html <http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html>`__
|
||||
|
||||
::
|
||||
|
||||
-b +/- sqrt(b^2 - 4 * a * c)
|
||||
-----------------------------
|
||||
2 * a
|
||||
|
||||
:math:`\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`
|
||||
|
||||
In
|
||||
`jp-quadratic.html <http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html>`__
|
||||
a Joy function for the Quadratic formula is derived (along with one of my favorite combinators ``[i] map``,
|
||||
which I like to call ``pam``) starting with a version written in Scheme. Here we investigate a different approach.
|
||||
|
||||
Write a program with variable names.
|
||||
====================================
|
||||
Write a straightforward program with variable names.
|
||||
----------------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
|
||||
We use ``cleave`` to compute the sum and difference ("plus-or-minus") and then ``app2`` to finish computing both roots using a quoted program ``[2a truediv]`` built with ``cons``.
|
||||
We use ``cleave`` to compute the sum and difference and then ``app2`` to
|
||||
finish computing both roots using a quoted program ``[2a truediv]``
|
||||
built with ``cons``.
|
||||
|
||||
Check it.
|
||||
~~~~~~~~~
|
||||
|
||||
Evaluating by hand::
|
||||
Evaluating by hand:
|
||||
|
||||
::
|
||||
|
||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
-b b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||
|
|
@ -38,19 +47,21 @@ Evaluating by hand::
|
|||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] app2
|
||||
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||
|
||||
(Eventually we'll be able to use e.g. Sympy versions of the Joy commands to do this sort of thing symbolically. This is part of what is meant by a "categorical" language.)
|
||||
(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands
|
||||
to do this sort of thing symbolically. This is part of what is meant by
|
||||
a “categorical” language.)
|
||||
|
||||
Cleanup
|
||||
~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a roll< pop
|
||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a -b pop
|
||||
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a roll< pop
|
||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a -b pop
|
||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||
|
||||
Derive a definition.
|
||||
====================
|
||||
--------------------
|
||||
|
||||
::
|
||||
|
||||
|
|
@ -60,10 +71,6 @@ Derive a definition.
|
|||
b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop
|
||||
b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
from notebook_preamble import J, V, define
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop')
|
||||
|
|
@ -79,13 +86,13 @@ Derive a definition.
|
|||
|
||||
|
||||
Simplify
|
||||
~~~~~~~~
|
||||
--------
|
||||
|
||||
We can define a ``pm`` plus-or-minus function:
|
||||
|
||||
.. code:: ipython2
|
||||
::
|
||||
|
||||
define('pm == [+] [-] cleave popdd')
|
||||
pm == [+] [-] cleave popdd
|
||||
|
||||
Then ``quadratic`` becomes:
|
||||
|
||||
|
|
@ -109,22 +116,15 @@ Define a "native" ``pm`` function.
|
|||
The definition of ``pm`` above is pretty elegant, but the implementation
|
||||
takes a lot of steps relative to what it's accomplishing. Since we are
|
||||
likely to use ``pm`` more than once in the future, let's write a
|
||||
primitive in Python and add it to the dictionary.
|
||||
primitive in Python and add it to the dictionary. (This has been done
|
||||
already.)
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
from joy.library import SimpleFunctionWrapper
|
||||
from notebook_preamble import D
|
||||
|
||||
|
||||
@SimpleFunctionWrapper
|
||||
def pm(stack):
|
||||
a, (b, stack) = stack
|
||||
p, m, = b + a, b - a
|
||||
return m, (p, stack)
|
||||
|
||||
|
||||
D['pm'] = pm
|
||||
|
||||
The resulting trace is short enough to fit on a page.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
Traversing Datastructures with Zippers
|
||||
======================================
|
||||
|
||||
This notebook is about using the "zipper" with joy datastructures. See
|
||||
the `Zipper wikipedia
|
||||
entry <https://en.wikipedia.org/wiki/Zipper_%28data_structure%29>`__ or
|
||||
|
|
@ -8,9 +11,6 @@ Huet <https://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-
|
|||
Given a datastructure on the stack we can navigate through it, modify
|
||||
it, and rebuild it using the "zipper" technique.
|
||||
|
||||
Preamble
|
||||
~~~~~~~~
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
from notebook_preamble import J, V, define
|
||||
|
|
|
|||
|
|
@ -12,9 +12,10 @@ These essays are adapted from Jupyter notebooks. I hope to have those hosted so
|
|||
Replacing
|
||||
Ordered_Binary_Trees
|
||||
Treestep
|
||||
Generator Programs
|
||||
Generator_Programs
|
||||
Newton-Raphson
|
||||
Quadratic
|
||||
Zipper
|
||||
NoUpdates
|
||||
Categorical
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,9 @@ while == swap [nullary] cons dup dipd concat loop
|
|||
dudipd == dup dipd
|
||||
primrec == [i] genrec
|
||||
step_zero == 0 roll> step
|
||||
codireco == cons dip rest cons
|
||||
make_generator == [codireco] ccons
|
||||
ccons == cons cons
|
||||
'''
|
||||
|
||||
##Zipper
|
||||
|
|
|
|||
Loading…
Reference in New Issue