Cleaning up docs.
This commit is contained in:
parent
956d849c8a
commit
507d045a3d
|
|
@ -11775,7 +11775,9 @@ div#notebook {
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -11796,7 +11798,11 @@ div#notebook {
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -11805,6 +11811,7 @@ div#notebook {
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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>
|
<p>$a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}$</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -11814,22 +11821,45 @@ div#notebook {
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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
|
<pre><code>a n over / + 2 /
|
||||||
---------------
|
|
||||||
(a+n/a)/2
|
|
||||||
|
|
||||||
n a tuck / + 2 /
|
|
||||||
a n a / + 2 /
|
a n a / + 2 /
|
||||||
a n/a + 2 /
|
a n/a + 2 /
|
||||||
a+n/a 2 /
|
a+n/a 2 /
|
||||||
(a+n/a)/2
|
(a+n/a)/2
|
||||||
|
|
||||||
</code></pre>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -11839,111 +11869,35 @@ a+n/a 2 /
|
||||||
<div class="prompt input_prompt">In [2]:</div>
|
<div class="prompt input_prompt">In [2]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [3]:</div>
|
<div class="prompt input_prompt">In [3]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [4]:</div>
|
<div class="prompt input_prompt">In [4]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
<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>
|
|
||||||
</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>
|
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -11960,38 +11914,7 @@ n a'' e ε K
|
||||||
|
|
||||||
|
|
||||||
<div class="output_subarea output_stream output_stdout output_text">
|
<div class="output_subarea output_stream output_stdout output_text">
|
||||||
<pre>5.000000232305737
|
<pre>[1 [dup 23 over / + 2 /] codireco]
|
||||||
</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>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -12004,9 +11927,101 @@ n a'' e ε K
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -12016,82 +12031,86 @@ n a'' e ε K
|
||||||
<div class="prompt input_prompt">In [7]:</div>
|
<div class="prompt input_prompt">In [7]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [8]:</div>
|
<div class="prompt input_prompt">In [8]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
|
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||||
</div>
|
</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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [9]:</div>
|
<div class="prompt input_prompt">In [9]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [10]:</div>
|
<div class="prompt input_prompt">In [10]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -12104,13 +12123,44 @@ n a'' e ε K
|
||||||
|
|
||||||
<div class="output_area">
|
<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">
|
<div class="output_text output_subarea output_execute_result">
|
||||||
<pre>4895048365636.0</pre>
|
<pre>22.999999999999996</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"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",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"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",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"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}$"
|
"$a_{i+1} = \\frac{(a_i+\\frac{n}{a_i})}{2}$"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -34,21 +47,41 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Let's define a function that computes the above equation:\n",
|
" a n over / + 2 /\n",
|
||||||
"\n",
|
|
||||||
" n a Q\n",
|
|
||||||
" ---------------\n",
|
|
||||||
" (a+n/a)/2\n",
|
|
||||||
"\n",
|
|
||||||
" n a tuck / + 2 /\n",
|
|
||||||
" a n a / + 2 /\n",
|
" a n a / + 2 /\n",
|
||||||
" a n/a + 2 /\n",
|
" a n/a + 2 /\n",
|
||||||
" a+n/a 2 /\n",
|
" a+n/a 2 /\n",
|
||||||
" (a+n/a)/2\n",
|
" (a+n/a)/2\n",
|
||||||
"\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",
|
"\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": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"define('Q == [tuck / + 2 /] unary')"
|
"define('codireco == cons dip rest cons')\n",
|
||||||
]
|
"define('make_generator == [codireco] ccons')\n",
|
||||||
},
|
"define('ccons == cons cons')"
|
||||||
{
|
|
||||||
"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"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 3,
|
||||||
"metadata": {},
|
"metadata": {
|
||||||
|
"scrolled": true
|
||||||
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"define('err == [sqr - abs] nullary')"
|
"define('gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator')"
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"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."
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 4,
|
"execution_count": 4,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"define('K == [<] [popop popd] [popd [Q err] dip] primrec')"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {
|
|
||||||
"scrolled": true
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"5.000000232305737\n"
|
"[1 [dup 23 over / + 2 /] codireco]\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"J('25 10 0.001 dup K')"
|
"J('23 gsra')"
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"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')"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"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",
|
"\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": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"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",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 8,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [],
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"6.000000000000007\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
"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",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 9,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [],
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"2212475.6192184356\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
"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",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"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": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"4895048365636.0"
|
"22.999999999999996"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 10,
|
"execution_count": 11,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"2212475.6192184356 * 2212475.6192184356"
|
"4.795831523312719**2"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1,140 +1,190 @@
|
||||||
|
|
||||||
# [Newton's method](https://en.wikipedia.org/wiki/Newton%27s_method)
|
# [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
|
```python
|
||||||
from notebook_preamble import J, V, define
|
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}$
|
$a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}$
|
||||||
|
|
||||||
Let's define a function that computes the above equation:
|
a n over / + 2 /
|
||||||
|
|
||||||
n a Q
|
|
||||||
---------------
|
|
||||||
(a+n/a)/2
|
|
||||||
|
|
||||||
n a tuck / + 2 /
|
|
||||||
a n a / + 2 /
|
a n a / + 2 /
|
||||||
a n/a + 2 /
|
a n/a + 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
|
```python
|
||||||
define('Q == [tuck / + 2 /] unary')
|
define('codireco == cons dip rest cons')
|
||||||
```
|
define('make_generator == [codireco] ccons')
|
||||||
|
define('ccons == cons cons')
|
||||||
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')
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
J('25 10 0.001 dup K')
|
define('gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator')
|
||||||
```
|
|
||||||
|
|
||||||
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')
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```python
|
```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
|
```python
|
||||||
J('4895048365636 square-root')
|
4.795831523312719**2
|
||||||
```
|
|
||||||
|
|
||||||
2212475.6192184356
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```python
|
|
||||||
2212475.6192184356 * 2212475.6192184356
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
4895048365636.0
|
22.999999999999996
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,172 +2,234 @@
|
||||||
`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
|
`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
|
.. code:: ipython2
|
||||||
|
|
||||||
from notebook_preamble import J, V, define
|
from notebook_preamble import J, V, define
|
||||||
|
|
||||||
Cf. `"Why Functional Programming Matters" by John
|
A Generator for Approximations
|
||||||
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
|
------------------------------
|
||||||
|
|
||||||
:math:`a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}`
|
To make a generator that generates successive approximations let’s start
|
||||||
|
by assuming an initial approximation and then derive the function that
|
||||||
Let's define a function that computes the above equation:
|
computes the next approximation:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
n a Q
|
a F
|
||||||
---------------
|
---------
|
||||||
(a+n/a)/2
|
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 /
|
||||||
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
|
.. code:: ipython2
|
||||||
|
|
||||||
define('Q == [tuck / + 2 /] unary')
|
define('codireco == cons dip rest cons')
|
||||||
|
define('make_generator == [codireco] ccons')
|
||||||
And a function to compute the error:
|
define('ccons == cons cons')
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython2
|
||||||
|
|
||||||
define('err == [sqr - abs] nullary')
|
define('gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator')
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython2
|
||||||
|
|
||||||
define('K == [<] [popop popd] [popd [Q err] dip] primrec')
|
J('23 gsra')
|
||||||
|
|
||||||
.. code:: ipython2
|
|
||||||
|
|
||||||
J('25 10 0.001 dup K')
|
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. 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
|
.. code:: ipython2
|
||||||
|
|
||||||
J('25 10 0.000001 dup K')
|
J('23 gsra 6 [x popd] times first sqr')
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
5.000000000000005
|
23.0000000001585
|
||||||
|
|
||||||
|
|
||||||
So now all we need is a way to generate an initial approximation and an
|
Finding Consecutive Approximations within a Tolerance
|
||||||
epsilon value:
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
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
|
.. 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
|
.. 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::
|
.. parsed-literal::
|
||||||
|
|
||||||
6.000000000000007
|
4.795831523312719
|
||||||
|
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython2
|
||||||
|
|
||||||
J('4895048365636 square-root')
|
4.795831523312719**2
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
|
||||||
|
|
||||||
2212475.6192184356
|
|
||||||
|
|
||||||
|
|
||||||
.. code:: ipython2
|
|
||||||
|
|
||||||
2212475.6192184356 * 2212475.6192184356
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
4895048365636.0
|
22.999999999999996
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11826,11 +11826,21 @@ div#notebook {
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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
|
<pre><code>b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||||
|
|
||||||
</code></pre>
|
</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
|
<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 sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||||
-b b^2 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] cons app2
|
||||||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] 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
|
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||||
|
|
||||||
</code></pre>
|
</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
|
<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 -b pop
|
||||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a</code></pre>
|
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a</code></pre>
|
||||||
|
|
@ -11855,7 +11875,7 @@ div#notebook {
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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
|
<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 [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
|
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>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||||
<div class="input">
|
</div>
|
||||||
<div class="prompt input_prompt">In [4]:</div>
|
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="text_cell_render border-box-sizing rendered_html">
|
||||||
<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>
|
<pre><code>pm == [+] [-] cleave popdd</code></pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -11942,7 +11959,7 @@ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truedi
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<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="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
<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>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<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="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
<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>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<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="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
<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="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>
|
|
||||||
<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">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="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="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>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -12028,7 +12037,7 @@ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truedi
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<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="inner_cell">
|
||||||
<div class="input_area">
|
<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>
|
<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",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"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",
|
" b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n",
|
||||||
"\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",
|
"### Check it.\n",
|
||||||
|
"Evaluating by hand:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\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",
|
" -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] cons app2\n",
|
||||||
" -b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] 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",
|
" -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 -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 -b pop\n",
|
||||||
" -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a"
|
" -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a"
|
||||||
|
|
@ -69,7 +86,7 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Derive a definition.\n",
|
"## Derive a definition.\n",
|
||||||
"\n",
|
"\n",
|
||||||
" b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop\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",
|
" b [neg] dupdip sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop\n",
|
||||||
|
|
@ -108,17 +125,15 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Simplify\n",
|
"## Simplify\n",
|
||||||
"We can define a `pm` plus-or-minus function:"
|
"We can define a `pm` plus-or-minus function:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "markdown",
|
||||||
"execution_count": 4,
|
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
"source": [
|
||||||
"define('pm == [+] [-] cleave popdd')"
|
" pm == [+] [-] cleave popdd"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -130,7 +145,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 5,
|
"execution_count": 4,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -139,7 +154,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 6,
|
"execution_count": 5,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -159,27 +174,19 @@
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Define a \"native\" `pm` function.\n",
|
"### 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",
|
"cell_type": "code",
|
||||||
"execution_count": 7,
|
"execution_count": 6,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from joy.library import SimpleFunctionWrapper\n",
|
|
||||||
"from notebook_preamble import D\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"@SimpleFunctionWrapper\n",
|
|
||||||
"def pm(stack):\n",
|
"def pm(stack):\n",
|
||||||
" a, (b, stack) = stack\n",
|
" a, (b, stack) = stack\n",
|
||||||
" p, m, = b + a, b - a\n",
|
" p, m, = b + a, b - a\n",
|
||||||
" return m, (p, stack)\n",
|
" return m, (p, stack)"
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"D['pm'] = pm"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -191,7 +198,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 8,
|
"execution_count": 7,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"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}$
|
$\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
|
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.
|
### Check it.
|
||||||
|
Evaluating by hand:
|
||||||
|
|
||||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
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 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] cons app2
|
||||||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] 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
|
-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 -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 -b pop
|
||||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
-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 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 [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
|
-0.3819660112501051 -2.618033988749895
|
||||||
|
|
||||||
|
|
||||||
### Simplify
|
## Simplify
|
||||||
We can define a `pm` plus-or-minus function:
|
We can define a `pm` plus-or-minus function:
|
||||||
|
|
||||||
|
pm == [+] [-] cleave popdd
|
||||||
```python
|
|
||||||
define('pm == [+] [-] cleave popdd')
|
|
||||||
```
|
|
||||||
|
|
||||||
Then `quadratic` becomes:
|
Then `quadratic` becomes:
|
||||||
|
|
||||||
|
|
@ -80,22 +84,14 @@ J('3 1 1 quadratic')
|
||||||
|
|
||||||
|
|
||||||
### Define a "native" `pm` function.
|
### 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
|
```python
|
||||||
from joy.library import SimpleFunctionWrapper
|
|
||||||
from notebook_preamble import D
|
|
||||||
|
|
||||||
|
|
||||||
@SimpleFunctionWrapper
|
|
||||||
def pm(stack):
|
def pm(stack):
|
||||||
a, (b, stack) = stack
|
a, (b, stack) = stack
|
||||||
p, m, = b + a, b - a
|
p, m, = b + a, b - a
|
||||||
return m, (p, stack)
|
return m, (p, stack)
|
||||||
|
|
||||||
|
|
||||||
D['pm'] = pm
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The resulting trace is short enough to fit on a page.
|
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}`
|
:math:`\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
|
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.
|
Check it.
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
|
Evaluating by hand:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
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) -b-sqrt(b^2-4ac) [2a truediv] app2
|
||||||
-b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
-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
|
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||||
|
|
||||||
Derive a definition.
|
Derive a definition.
|
||||||
====================
|
--------------------
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
@ -76,13 +86,13 @@ Derive a definition.
|
||||||
|
|
||||||
|
|
||||||
Simplify
|
Simplify
|
||||||
~~~~~~~~
|
--------
|
||||||
|
|
||||||
We can define a ``pm`` plus-or-minus function:
|
We can define a ``pm`` plus-or-minus function:
|
||||||
|
|
||||||
.. code:: ipython2
|
::
|
||||||
|
|
||||||
define('pm == [+] [-] cleave popdd')
|
pm == [+] [-] cleave popdd
|
||||||
|
|
||||||
Then ``quadratic`` becomes:
|
Then ``quadratic`` becomes:
|
||||||
|
|
||||||
|
|
@ -106,23 +116,16 @@ Define a "native" ``pm`` function.
|
||||||
The definition of ``pm`` above is pretty elegant, but the implementation
|
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
|
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
|
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
|
.. code:: ipython2
|
||||||
|
|
||||||
from joy.library import SimpleFunctionWrapper
|
|
||||||
from notebook_preamble import D
|
|
||||||
|
|
||||||
|
|
||||||
@SimpleFunctionWrapper
|
|
||||||
def pm(stack):
|
def pm(stack):
|
||||||
a, (b, stack) = stack
|
a, (b, stack) = stack
|
||||||
p, m, = b + a, b - a
|
p, m, = b + a, b - a
|
||||||
return m, (p, stack)
|
return m, (p, stack)
|
||||||
|
|
||||||
|
|
||||||
D['pm'] = pm
|
|
||||||
|
|
||||||
The resulting trace is short enough to fit on a page.
|
The resulting trace is short enough to fit on a page.
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython2
|
||||||
|
|
|
||||||
|
|
@ -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/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/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/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/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/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/NoUpdates.html">No Updates</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="notebooks/Categorical.html">Categorical Programming</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="notebooks/Categorical.html">Categorical Programming</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -34,18 +34,25 @@
|
||||||
|
|
||||||
<div class="section" id="quadratic-formula">
|
<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>
|
<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><span class="math notranslate nohighlight">\(\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\)</span></p>
|
||||||
<p>In
|
<div class="section" id="write-a-straightforward-program-with-variable-names">
|
||||||
<a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html">jp-quadratic.html</a>
|
<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>
|
||||||
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="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>
|
<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>
|
</pre></div>
|
||||||
</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">
|
<div class="section" id="check-it">
|
||||||
<h3>Check it.<a class="headerlink" href="#check-it" title="Permalink to this headline">¶</a></h3>
|
<h3>Check it.<a class="headerlink" href="#check-it" title="Permalink to this headline">¶</a></h3>
|
||||||
<p>Evaluating by hand:</p>
|
<p>Evaluating by hand:</p>
|
||||||
|
|
@ -62,7 +69,9 @@ 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>
|
<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>
|
</pre></div>
|
||||||
</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>
|
||||||
<div class="section" id="cleanup">
|
<div class="section" id="cleanup">
|
||||||
<h3>Cleanup<a class="headerlink" href="#cleanup" title="Permalink to this headline">¶</a></h3>
|
<h3>Cleanup<a class="headerlink" href="#cleanup" title="Permalink to this headline">¶</a></h3>
|
||||||
|
|
@ -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>
|
<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>
|
</pre></div>
|
||||||
</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>
|
<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>
|
</pre></div>
|
||||||
</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>
|
<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>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="section" id="simplify">
|
<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>
|
<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>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
<p>Then <code class="docutils literal notranslate"><span class="pre">quadratic</span></code> becomes:</p>
|
<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>
|
<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>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="section" id="define-a-native-pm-function">
|
<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>
|
<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
|
<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
|
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
|
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>
|
primitive in Python and add it to the dictionary. (This has been done
|
||||||
<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>
|
already.)</p>
|
||||||
<span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span>
|
<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="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>
|
|
||||||
<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">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="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="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>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
<p>The resulting trace is short enough to fit on a page.</p>
|
<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>
|
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a class="reference internal" href="#">Quadratic formula</a><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="#check-it">Check it.</a></li>
|
||||||
<li><a class="reference internal" href="#cleanup">Cleanup</a></li>
|
<li><a class="reference internal" href="#cleanup">Cleanup</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#derive-a-definition">Derive a definition.</a><ul>
|
<li><a class="reference internal" href="#derive-a-definition">Derive a definition.</a></li>
|
||||||
<li><a class="reference internal" href="#simplify">Simplify</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>
|
<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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<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/alabaster.css" type="text/css" />
|
||||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||||
<script type="text/javascript" src="../_static/documentation_options.js"></script>
|
<script type="text/javascript" src="../_static/documentation_options.js"></script>
|
||||||
|
|
@ -30,15 +30,15 @@
|
||||||
<div class="bodywrapper">
|
<div class="bodywrapper">
|
||||||
<div class="body" role="main">
|
<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
|
the <a class="reference external" href="https://en.wikipedia.org/wiki/Zipper_%28data_structure%29">Zipper wikipedia
|
||||||
entry</a> or
|
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
|
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>
|
Huet</a></p>
|
||||||
<p>Given a datastructure on the stack we can navigate through it, modify
|
<p>Given a datastructure on the stack we can navigate through it, modify
|
||||||
it, and rebuild it using the “zipper” technique.</p>
|
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>
|
<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>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -309,7 +309,7 @@ i d i d i d d Bingo!
|
||||||
<div class="sphinxsidebarwrapper">
|
<div class="sphinxsidebarwrapper">
|
||||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||||
<ul>
|
<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="#trees">Trees</a></li>
|
||||||
<li><a class="reference internal" href="#zipper-in-joy">Zipper in Joy</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>
|
<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>
|
<li class="toctree-l2"><a class="reference internal" href="Treestep.html#putting-it-together">Putting it together</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</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-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#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#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#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#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#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#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#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-l2"><a class="reference internal" href="Generator_Programs.html#an-interesting-variation">An Interesting Variation</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a><ul>
|
<li class="toctree-l1"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a><ul>
|
||||||
|
|
@ -91,8 +91,18 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="Quadratic.html">Quadratic formula</a><ul>
|
<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#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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="NoUpdates.html">No Updates</a></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
|
Generating Multiples of Three and Five
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
Look at the treatment of the Project Euler Problem One in `Developing a
|
Look at the treatment of the Project Euler Problem One in the
|
||||||
Program.ipynb <./Developing%20a%20Program.ipynb>`__ and you'll see that
|
"Developing a Program" notebook and you'll see that we might be
|
||||||
we might be interested in generating an endless cycle of:
|
interested in generating an endless cycle of:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
@ -1,30 +1,39 @@
|
||||||
|
|
||||||
***********************************************************************
|
|
||||||
`Quadratic formula <https://en.wikipedia.org/wiki/Quadratic_formula>`__
|
`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}`
|
:math:`\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`
|
||||||
|
|
||||||
In
|
Write a straightforward program with variable names.
|
||||||
`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.
|
|
||||||
====================================
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
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.
|
Check it.
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
Evaluating by hand::
|
Evaluating by hand:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
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 sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
|
||||||
|
|
@ -38,7 +47,9 @@ Evaluating by hand::
|
||||||
-b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] 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
|
-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
|
Cleanup
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
@ -50,7 +61,7 @@ Cleanup
|
||||||
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
-b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
|
||||||
|
|
||||||
Derive a definition.
|
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 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
|
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
|
.. code:: ipython2
|
||||||
|
|
||||||
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop')
|
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
|
Simplify
|
||||||
~~~~~~~~
|
--------
|
||||||
|
|
||||||
We can define a ``pm`` plus-or-minus function:
|
We can define a ``pm`` plus-or-minus function:
|
||||||
|
|
||||||
.. code:: ipython2
|
::
|
||||||
|
|
||||||
define('pm == [+] [-] cleave popdd')
|
pm == [+] [-] cleave popdd
|
||||||
|
|
||||||
Then ``quadratic`` becomes:
|
Then ``quadratic`` becomes:
|
||||||
|
|
||||||
|
|
@ -109,23 +116,16 @@ Define a "native" ``pm`` function.
|
||||||
The definition of ``pm`` above is pretty elegant, but the implementation
|
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
|
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
|
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
|
.. code:: ipython2
|
||||||
|
|
||||||
from joy.library import SimpleFunctionWrapper
|
|
||||||
from notebook_preamble import D
|
|
||||||
|
|
||||||
|
|
||||||
@SimpleFunctionWrapper
|
|
||||||
def pm(stack):
|
def pm(stack):
|
||||||
a, (b, stack) = stack
|
a, (b, stack) = stack
|
||||||
p, m, = b + a, b - a
|
p, m, = b + a, b - a
|
||||||
return m, (p, stack)
|
return m, (p, stack)
|
||||||
|
|
||||||
|
|
||||||
D['pm'] = pm
|
|
||||||
|
|
||||||
The resulting trace is short enough to fit on a page.
|
The resulting trace is short enough to fit on a page.
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython2
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
|
||||||
|
Traversing Datastructures with Zippers
|
||||||
|
======================================
|
||||||
|
|
||||||
This notebook is about using the "zipper" with joy datastructures. See
|
This notebook is about using the "zipper" with joy datastructures. See
|
||||||
the `Zipper wikipedia
|
the `Zipper wikipedia
|
||||||
entry <https://en.wikipedia.org/wiki/Zipper_%28data_structure%29>`__ or
|
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
|
Given a datastructure on the stack we can navigate through it, modify
|
||||||
it, and rebuild it using the "zipper" technique.
|
it, and rebuild it using the "zipper" technique.
|
||||||
|
|
||||||
Preamble
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython2
|
||||||
|
|
||||||
from notebook_preamble import J, V, define
|
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
|
Replacing
|
||||||
Ordered_Binary_Trees
|
Ordered_Binary_Trees
|
||||||
Treestep
|
Treestep
|
||||||
Generator Programs
|
Generator_Programs
|
||||||
Newton-Raphson
|
Newton-Raphson
|
||||||
Quadratic
|
Quadratic
|
||||||
|
Zipper
|
||||||
NoUpdates
|
NoUpdates
|
||||||
Categorical
|
Categorical
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,9 @@ while == swap [nullary] cons dup dipd concat loop
|
||||||
dudipd == dup dipd
|
dudipd == dup dipd
|
||||||
primrec == [i] genrec
|
primrec == [i] genrec
|
||||||
step_zero == 0 roll> step
|
step_zero == 0 roll> step
|
||||||
|
codireco == cons dip rest cons
|
||||||
|
make_generator == [codireco] ccons
|
||||||
|
ccons == cons cons
|
||||||
'''
|
'''
|
||||||
|
|
||||||
##Zipper
|
##Zipper
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue