4 "cell_type": "markdown",
7 "# [Newton's method](https://en.wikipedia.org/wiki/Newton%27s_method)\n",
8 "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",
10 "Cf. [\"Why Functional Programming Matters\" by John Hughes](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf)"
19 "from notebook_preamble import J, V, define"
23 "cell_type": "markdown",
26 "## A Generator for Approximations\n",
28 "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",
36 "cell_type": "markdown",
39 "### A Function to Compute the Next Approximation\n",
41 "This is the equation for computing the next approximate value of the square root:\n",
43 "$a_{i+1} = \\frac{(a_i+\\frac{n}{a_i})}{2}$"
47 "cell_type": "markdown",
50 " a n over / + 2 /\n",
56 "The function we want has the argument `n` in it:\n",
58 " F == n over / + 2 /"
62 "cell_type": "markdown",
65 "### Make it into a Generator\n",
67 "Our generator would be created by:\n",
69 " a [dup F] make_generator\n",
71 "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",
79 "The generator can be written as:\n",
81 " 23 1 swap [over / + 2 /] cons [dup] swoncat make_generator\n",
82 " 1 23 [over / + 2 /] cons [dup] swoncat make_generator\n",
83 " 1 [23 over / + 2 /] [dup] swoncat make_generator\n",
84 " 1 [dup 23 over / + 2 /] make_generator"
95 "define('gsra 1 swap [over / + 2 /] cons [dup] swoncat make_generator')"
100 "execution_count": 3,
105 "output_type": "stream",
107 "[1 [dup 23 over / + 2 /] codireco]\n"
116 "cell_type": "markdown",
119 "Let's drive the generator a few time (with the `x` combinator) and square the approximation to see how well it works..."
124 "execution_count": 4,
129 "output_type": "stream",
136 "J('23 gsra 6 [x popd] times first sqr')"
140 "cell_type": "markdown",
143 "## Finding Consecutive Approximations within a Tolerance\n",
145 "From [\"Why Functional Programming Matters\" by John Hughes](https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf):\n",
148 "> 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",
150 "(And note that by “list” he means a lazily-evaluated list.)\n",
152 "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",
154 " a [b G] ε within\n",
155 " ---------------------- a b - abs ε <=\n",
159 " a [b G] ε within\n",
160 " ---------------------- a b - abs ε >\n",
161 " b [c G] ε within\n",
166 "cell_type": "markdown",
171 " a [b G] ε [first - abs] dip <=\n",
172 " a [b G] first - abs ε <=\n",
181 "execution_count": 5,
185 "define('_within_P [first - abs] dip <=')"
189 "cell_type": "markdown",
194 " a [b G] ε roll< popop first\n",
195 " [b G] ε a popop first\n",
202 "execution_count": 6,
206 "define('_within_B roll< popop first')"
210 "cell_type": "markdown",
215 " a [b G] ε R0 [within] R1\n",
218 "2. Use `x` combinator to generate next term from `G`.\n",
219 "3. Run `within` with `i` (it is a \"tail-recursive\" function.)\n",
221 "Pretty straightforward:\n",
223 " a [b G] ε R0 [within] R1\n",
224 " a [b G] ε [popd x] dip [within] i\n",
225 " a [b G] popd x ε [within] i\n",
226 " [b G] x ε [within] i\n",
227 " b [c G] ε [within] i\n",
228 " b [c G] ε within\n",
235 "execution_count": 7,
239 "define('_within_R [popd x] dip')"
243 "cell_type": "markdown",
248 "The recursive function we have defined so far needs a slight preamble: `x` to prime the generator and the epsilon value to use:\n",
256 "execution_count": 8,
260 "define('within x 0.000000001 [_within_P] [_within_B] [_within_R] tailrec')\n",
261 "define('sqrt gsra within')"
265 "cell_type": "markdown",
273 "execution_count": 9,
280 "output_type": "stream",
292 "execution_count": 10,
299 "output_type": "stream",
301 "4.795831523312719\n"
310 "cell_type": "markdown",
318 "execution_count": 11,
329 "execution_count": 11,
331 "output_type": "execute_result"
335 "4.795831523312719**2"
340 "execution_count": 12,
349 "execution_count": 12,
351 "output_type": "execute_result"
355 "from math import sqrt\n",
363 "display_name": "Python 2",
364 "language": "python",
372 "file_extension": ".py",
373 "mimetype": "text/x-python",
375 "nbconvert_exporter": "python",
376 "pygments_lexer": "ipython3",