{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# [Quadratic formula](https://en.wikipedia.org/wiki/Quadratic_formula)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from notebook_preamble import J, V, define" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cf. [jp-quadratic.html](http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " -b +/- sqrt(b^2 - 4 * a * c)\n", " -----------------------------\n", " 2 * a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Write a straightforward program with variable names.\n", " b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n", "\n", "### Check it.\n", "\n", " b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n", " -b b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n", " -b b^2 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n", " -b b^2 4ac - sqrt [+] [-] cleave a 2 * [truediv] cons app2\n", " -b b^2-4ac sqrt [+] [-] cleave a 2 * [truediv] cons app2\n", " -b sqrt(b^2-4ac) [+] [-] cleave a 2 * [truediv] cons app2\n", "\n", " -b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) a 2 * [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)/2a -b-sqrt(b^2-4ac)/2a\n", "### Codicil\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" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Derive a definition.\n", "\n", " b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop\n", " b [neg] dupdip sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop\n", " b a c [[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop\n", " b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop\n", " b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-0.3819660112501051 -2.618033988749895\n" ] } ], "source": [ "J('3 1 1 quadratic')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Simplify\n", "We can define a `pm` plus-or-minus function:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "define('pm == [+] [-] cleave popdd')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then `quadratic` becomes:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2')" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-0.3819660112501051 -2.618033988749895\n" ] } ], "source": [ "J('3 1 1 quadratic')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Define a \"native\" `pm` function.\n", "The definition of `pm` above is pretty elegant, but the implementation takes a lot of steps relative to what it's accomplishing. Since we are likely to use `pm` more than once in the future, let's write a primitive in Python and add it to the dictionary." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "from joy.library import SimpleFunctionWrapper\n", "from notebook_preamble import D\n", "\n", "\n", "@SimpleFunctionWrapper\n", "def pm(stack):\n", " a, (b, stack) = stack\n", " p, m, = b + a, b - a\n", " return m, (p, stack)\n", "\n", "\n", "D['pm'] = pm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The resulting trace is short enough to fit on a page." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " . 3 1 1 quadratic\n", " 3 . 1 1 quadratic\n", " 3 1 . 1 quadratic\n", " 3 1 1 . quadratic\n", " 3 1 1 . over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2\n", " 3 1 1 1 . [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2\n", " 3 1 1 1 [[[neg] dupdip sqr 4] dipd * * - sqrt pm] . dip 2 * [truediv] cons app2\n", " 3 1 1 . [[neg] dupdip sqr 4] dipd * * - sqrt pm 1 2 * [truediv] cons app2\n", " 3 1 1 [[neg] dupdip sqr 4] . dipd * * - sqrt pm 1 2 * [truediv] cons app2\n", " 3 . [neg] dupdip sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " 3 [neg] . dupdip sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " 3 . neg 3 sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 . 3 sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 3 . sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 3 . dup mul 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 3 3 . mul 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 9 . 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 9 4 . 1 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 9 4 1 . 1 * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 9 4 1 1 . * * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 9 4 1 . * - sqrt pm 1 2 * [truediv] cons app2\n", " -3 9 4 . - sqrt pm 1 2 * [truediv] cons app2\n", " -3 5 . sqrt pm 1 2 * [truediv] cons app2\n", " -3 2.23606797749979 . pm 1 2 * [truediv] cons app2\n", " -0.7639320225002102 -5.23606797749979 . 1 2 * [truediv] cons app2\n", " -0.7639320225002102 -5.23606797749979 1 . 2 * [truediv] cons app2\n", " -0.7639320225002102 -5.23606797749979 1 2 . * [truediv] cons app2\n", " -0.7639320225002102 -5.23606797749979 2 . [truediv] cons app2\n", " -0.7639320225002102 -5.23606797749979 2 [truediv] . cons app2\n", " -0.7639320225002102 -5.23606797749979 [2 truediv] . app2\n", " [-0.7639320225002102] [2 truediv] . infra first [-5.23606797749979] [2 truediv] infra first\n", " -0.7639320225002102 . 2 truediv [] swaack first [-5.23606797749979] [2 truediv] infra first\n", " -0.7639320225002102 2 . truediv [] swaack first [-5.23606797749979] [2 truediv] infra first\n", " -0.3819660112501051 . [] swaack first [-5.23606797749979] [2 truediv] infra first\n", " -0.3819660112501051 [] . swaack first [-5.23606797749979] [2 truediv] infra first\n", " [-0.3819660112501051] . first [-5.23606797749979] [2 truediv] infra first\n", " -0.3819660112501051 . [-5.23606797749979] [2 truediv] infra first\n", " -0.3819660112501051 [-5.23606797749979] . [2 truediv] infra first\n", "-0.3819660112501051 [-5.23606797749979] [2 truediv] . infra first\n", " -5.23606797749979 . 2 truediv [-0.3819660112501051] swaack first\n", " -5.23606797749979 2 . truediv [-0.3819660112501051] swaack first\n", " -2.618033988749895 . [-0.3819660112501051] swaack first\n", " -2.618033988749895 [-0.3819660112501051] . swaack first\n", " -0.3819660112501051 [-2.618033988749895] . first\n", " -0.3819660112501051 -2.618033988749895 . \n" ] } ], "source": [ "V('3 1 1 quadratic')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.13" } }, "nbformat": 4, "nbformat_minor": 2 }