changeset 2:b4de894a1e2e

initial import
author Robert McIntyre <rlm@mit.edu>
date Fri, 28 Oct 2011 00:03:05 -0700
parents 8d8278e09888
children 44d3dc936f6a
files categorical/imperative.html categorical/imperative.org categorical/ltxpng/plausible_0dd51e4ab8cb4eb616439d758fbec4ed120e8a15.png categorical/ltxpng/plausible_327b1246bf52889b71445e990ea38a8414f683cc.png categorical/ltxpng/plausible_34a4f0f7fd91bf7212f437fd9e0fae7c04dbdae1.png categorical/ltxpng/plausible_5072ddd55abeb45994e1f467e2041032d8a90350.png categorical/ltxpng/plausible_5434f18d3d7ac2858cd4f914be8f5d2b49c79a90.png categorical/ltxpng/plausible_60c89d70f35bbeef7c8c5572941c3398e65f9eb1.png categorical/ltxpng/plausible_671e7f9a1d6c0ed854ad469bb2e6446cf536f6ce.png categorical/ltxpng/plausible_70e445784826d50e75fa759496de7dbd78e0c29e.png categorical/ltxpng/plausible_9471153ffb8045fd30a14628197f6e1a31c4d2bf.png categorical/ltxpng/plausible_c0cfa0be1f5f4c93c4a07d2bf03f296a87ddb3f5.png categorical/ltxpng/plausible_d282b164f31f8cb4d3238ea37d09715da89272aa.png categorical/ltxpng/plausible_dd81a36f0fc30866fc59a06fba09770696fbcfce.png categorical/ltxpng/plausible_df22ff07c07c3eae08269551b79e75e13ed321f9.png categorical/monad.clj categorical/monad.html categorical/monad.org categorical/morphisms.html categorical/morphisms.org categorical/plausible.html categorical/plausible.org categorical/plausible.org_archive categorical/synthetic.html categorical/synthetic.org chat/room.clj clojure_magick/magick.clj mtg/bk.clj mtg/continuation.clj mtg/frame.clj mtg/mtg_cards.txt org/science.org proof.org sicm.org sicm/bk/utils.clj sicm/bk/utils.html sicm/bk/utils.org sicm/deriv.html sicm/deriv.org sicm/notes.html sicm/notes.org sicm/utils.clj sicm/utils.html sicm/utils.org
diffstat 43 files changed, 9438 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/categorical/imperative.html	Fri Oct 28 00:03:05 2011 -0700
     1.3 @@ -0,0 +1,1207 @@
     1.4 +<?xml version="1.0" encoding="utf-8"?>
     1.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     1.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
     1.7 +<html xmlns="http://www.w3.org/1999/xhtml"
     1.8 +lang="en" xml:lang="en">
     1.9 +<head>
    1.10 +<title>LAMBDA: The Ultimate Imperative</title>
    1.11 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    1.12 +<meta name="generator" content="Org-mode"/>
    1.13 +<meta name="generated" content="2011-07-15 02:49:04 EDT"/>
    1.14 +<meta name="author" content="Guy Lewis Steele Jr. and Gerald Jay Sussman"/>
    1.15 +<meta name="description" content=""/>
    1.16 +<meta name="keywords" content=""/>
    1.17 +<style type="text/css">
    1.18 + <!--/*--><![CDATA[/*><!--*/
    1.19 +  html { font-family: Times, serif; font-size: 12pt; }
    1.20 +  .title  { text-align: center; }
    1.21 +  .todo   { color: red; }
    1.22 +  .done   { color: green; }
    1.23 +  .tag    { background-color: #add8e6; font-weight:normal }
    1.24 +  .target { }
    1.25 +  .timestamp { color: #bebebe; }
    1.26 +  .timestamp-kwd { color: #5f9ea0; }
    1.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
    1.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
    1.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
    1.30 +  p.verse { margin-left: 3% }
    1.31 +  pre {
    1.32 +	border: 1pt solid #AEBDCC;
    1.33 +	background-color: #F3F5F7;
    1.34 +	padding: 5pt;
    1.35 +	font-family: courier, monospace;
    1.36 +        font-size: 90%;
    1.37 +        overflow:auto;
    1.38 +  }
    1.39 +  table { border-collapse: collapse; }
    1.40 +  td, th { vertical-align: top;  }
    1.41 +  th.right  { text-align:center;  }
    1.42 +  th.left   { text-align:center;   }
    1.43 +  th.center { text-align:center; }
    1.44 +  td.right  { text-align:right;  }
    1.45 +  td.left   { text-align:left;   }
    1.46 +  td.center { text-align:center; }
    1.47 +  dt { font-weight: bold; }
    1.48 +  div.figure { padding: 0.5em; }
    1.49 +  div.figure p { text-align: center; }
    1.50 +  textarea { overflow-x: auto; }
    1.51 +  .linenr { font-size:smaller }
    1.52 +  .code-highlighted {background-color:#ffff00;}
    1.53 +  .org-info-js_info-navigation { border-style:none; }
    1.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
    1.55 +                               white-space:nowrap; }
    1.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
    1.57 +                                 font-weight:bold; }
    1.58 +  /*]]>*/-->
    1.59 +</style>
    1.60 +<script type="text/javascript">
    1.61 +<!--/*--><![CDATA[/*><!--*/
    1.62 + function CodeHighlightOn(elem, id)
    1.63 + {
    1.64 +   var target = document.getElementById(id);
    1.65 +   if(null != target) {
    1.66 +     elem.cacheClassElem = elem.className;
    1.67 +     elem.cacheClassTarget = target.className;
    1.68 +     target.className = "code-highlighted";
    1.69 +     elem.className   = "code-highlighted";
    1.70 +   }
    1.71 + }
    1.72 + function CodeHighlightOff(elem, id)
    1.73 + {
    1.74 +   var target = document.getElementById(id);
    1.75 +   if(elem.cacheClassElem)
    1.76 +     elem.className = elem.cacheClassElem;
    1.77 +   if(elem.cacheClassTarget)
    1.78 +     target.className = elem.cacheClassTarget;
    1.79 + }
    1.80 +/*]]>*///-->
    1.81 +</script>
    1.82 +<script type="text/javascript" src="http://orgmode.org/mathjax/MathJax.js">
    1.83 +<!--/*--><![CDATA[/*><!--*/
    1.84 +    MathJax.Hub.Config({
    1.85 +        // Only one of the two following lines, depending on user settings
    1.86 +        // First allows browser-native MathML display, second forces HTML/CSS
    1.87 +        //  config: ["MMLorHTML.js"], jax: ["input/TeX"],
    1.88 +            jax: ["input/TeX", "output/HTML-CSS"],
    1.89 +        extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js",
    1.90 +                     "TeX/noUndefined.js"],
    1.91 +        tex2jax: {
    1.92 +            inlineMath: [ ["\\(","\\)"] ],
    1.93 +            displayMath: [ ['$$','$$'], ["\\[","\\]"], ["\\begin{displaymath}","\\end{displaymath}"] ],
    1.94 +            skipTags: ["script","noscript","style","textarea","pre","code"],
    1.95 +            ignoreClass: "tex2jax_ignore",
    1.96 +            processEscapes: false,
    1.97 +            processEnvironments: true,
    1.98 +            preview: "TeX"
    1.99 +        },
   1.100 +        showProcessingMessages: true,
   1.101 +        displayAlign: "center",
   1.102 +        displayIndent: "2em",
   1.103 +
   1.104 +        "HTML-CSS": {
   1.105 +             scale: 100,
   1.106 +             availableFonts: ["STIX","TeX"],
   1.107 +             preferredFont: "TeX",
   1.108 +             webFont: "TeX",
   1.109 +             imageFont: "TeX",
   1.110 +             showMathMenu: true,
   1.111 +        },
   1.112 +        MMLorHTML: {
   1.113 +             prefer: {
   1.114 +                 MSIE:    "MML",
   1.115 +                 Firefox: "MML",
   1.116 +                 Opera:   "HTML",
   1.117 +                 other:   "HTML"
   1.118 +             }
   1.119 +        }
   1.120 +    });
   1.121 +/*]]>*///-->
   1.122 +</script>
   1.123 +</head>
   1.124 +<body>
   1.125 +
   1.126 +<div id="content">
   1.127 +
   1.128 +
   1.129 +
   1.130 +<div id="table-of-contents">
   1.131 +<h2>Table of Contents</h2>
   1.132 +<div id="text-table-of-contents">
   1.133 +<ul>
   1.134 +<li><a href="#sec-1">1 Abstract </a></li>
   1.135 +<li><a href="#sec-2">2 Introduction </a>
   1.136 +<ul>
   1.137 +<li><a href="#sec-2-1">2.1 Simple Loops </a>
   1.138 +<ul>
   1.139 +<li><a href="#sec-2-1-1">2.1.1 Simple Recursion </a></li>
   1.140 +<li><a href="#sec-2-1-2">2.1.2 Iteration </a></li>
   1.141 +</ul></li>
   1.142 +</ul>
   1.143 +</li>
   1.144 +<li><a href="#sec-3">3 Imperative Programming </a>
   1.145 +<ul>
   1.146 +<li><a href="#sec-3-1">3.1 Compound Statements </a></li>
   1.147 +<li><a href="#sec-3-2">3.2 2.2. The G0 TO Statement </a></li>
   1.148 +<li><a href="#sec-3-3">3.3 2.3. Simple Assignment </a></li>
   1.149 +<li><a href="#sec-3-4">3.4 Compound Expressions ' </a></li>
   1.150 +</ul>
   1.151 +</li>
   1.152 +<li><a href="#sec-4">4 Continuations </a>
   1.153 +<ul>
   1.154 +<li><a href="#sec-4-1">4.1 Continuation-Passing Recursion </a></li>
   1.155 +<li><a href="#sec-4-2">4.2 Escape Expressions </a></li>
   1.156 +</ul>
   1.157 +</li>
   1.158 +</ul>
   1.159 +</div>
   1.160 +</div>
   1.161 +
   1.162 +<div id="outline-container-1" class="outline-2">
   1.163 +<h2 id="sec-1"><span class="section-number-2">1</span> Abstract </h2>
   1.164 +<div class="outline-text-2" id="text-1">
   1.165 +
   1.166 +
   1.167 +<p>
   1.168 +We demonstrate how to model the following common programming constructs in
   1.169 +terms of an applicative order language similar to LISP:
   1.170 +</p><ul>
   1.171 +<li>Simple Recursion
   1.172 +</li>
   1.173 +<li>Iteration 
   1.174 +</li>
   1.175 +<li>Compound Statements and Expressions
   1.176 +</li>
   1.177 +<li>GO TO and Assignment
   1.178 +</li>
   1.179 +<li>Continuation—Passing
   1.180 +</li>
   1.181 +<li>Escape Expressions
   1.182 +</li>
   1.183 +<li>Fluid Variables
   1.184 +</li>
   1.185 +<li>Call by Name, Call by Need, and Call by Reference
   1.186 +</li>
   1.187 +</ul>
   1.188 +
   1.189 +<p>The models require only (possibly self-referent) lambda application,
   1.190 +conditionals, and (rarely) assignment. No complex data structures such as
   1.191 +stacks are used. The models are transparent, involving only local syntactic
   1.192 +transformations.
   1.193 +Some of these models, such as those for GO TO and assignment, are already well
   1.194 +known, and appear in the work of Landin, Reynolds, and others. The models for
   1.195 +escape expressions, fluid variables, and call by need with side effects are
   1.196 +new. This paper is partly tutorial in intent, gathering all the models
   1.197 +together for purposes of context.
   1.198 +This report describes research done at the Artificial Intelligence Laboratory
   1.199 +of the Massachusetts Institute of Teehnology. Support for the laboratory's
   1.200 +artificial intelligence research is provided in part by the Advanced Research
   1.201 +Projects Agency of the Department of Defense under Office of Naval Research
   1.202 +contract N000l4-75-C-0643.
   1.203 +</p>
   1.204 +</div>
   1.205 +
   1.206 +</div>
   1.207 +
   1.208 +<div id="outline-container-2" class="outline-2">
   1.209 +<h2 id="sec-2"><span class="section-number-2">2</span> Introduction </h2>
   1.210 +<div class="outline-text-2" id="text-2">
   1.211 +
   1.212 +
   1.213 +<p>
   1.214 + We catalogue a number of common programming constructs. For each
   1.215 +construct we examine "typical" usage in well-known programming languages, and
   1.216 +then capture the essence of the semantics of the construct in terms of a
   1.217 +common meta-language.
   1.218 +The lambda calculus {Note Alonzowins} is often used as such a meta-
   1.219 +language. Lambda calculus offers clean semantics, but it is clumsy because it
   1.220 +was designed to be a minimal language rather than a convenient one. All
   1.221 +lambda calculus "functions" must take exactly one "argument"; the only "data
   1.222 +type" is lambda expressions; and the only "primitive operation‘ is variable‘
   1.223 +substitution. While its utter simplicity makes lambda calculus ideal for
   1.224 +logicians, it is too primitive for use by programmers. The meta-language we
   1.225 +use is a programming language called SCHEME {Note Schemepaper) which is based
   1.226 +on lambda calculus.
   1.227 +SCHEME is a dialect of LISP. [McCarthy 62] It is an expression-
   1.228 +oriented, applicative order, interpreter-based language which allows one to
   1.229 +manipulate programs as data. It differs from most current dialects of LISP in
   1.230 +that it closes all lambda expressions in the environment of their definition
   1.231 +or declaration, rather than in the execution environment. {Note Closures}
   1.232 +This preserves the substitution semantics of lambda calculus, and has the
   1.233 +consequence that all variables are lexically scoped, as in ALGOL. [Naur 63]
   1.234 +Another difference is that SCHEME is implemented in such a way that tail-
   1.235 +recursions execute without net growth of the interpreter stack. {Note
   1.236 +Schemenote} We have chosen to use LISP syntax rather than, say, ALGOL syntax
   1.237 +because we want to treat programs as data for the purpose of describing
   1.238 +transformations on the code. LISP supplies names for the parts of an
   1.239 +executable expression and standard operators for constructing expressions and
   1.240 +extracting their components. The use of LISP syntax makes the structure of
   1.241 +such expressions manifest. We use ALGOL as an expository language, because it
   1.242 +is familiar to many people, but ALGOL is not sufficiently powerful to express
   1.243 +the necessary concepts; in particular, it does not allow functions to return
   1.244 +functions as values. we are thus forced to use a dialect of LISP in many
   1.245 +cases.
   1.246 +We will consider various complex programming language constructs and
   1.247 +show how to model them in terms of only a few simple ones. As far as possible
   1.248 +we will use only three control constructs from SCHEME: LAMBDA expressions, as
   1.249 +in LISP, which are Just functions with lexically scoped free variables;
   1.250 +LABELS, which allows declaration of mutually recursive procedures (Note
   1.251 +Labelsdef}; and IF, a primitive conditional expression. For more complex
   1.252 +modelling we will introduce an assignment primitive (ASET).i We will freely
   1.253 +assume the existence of other comon primitives, such as arithmetic functions.
   1.254 +The constructs we will examine are divided into four broad classes.
   1.255 +The first is sfinph?Lo0pl; this contains simple recursions and iterations, and
   1.256 +an introduction to the notion of continuations. The second is hmponflivo
   1.257 +Connrucls; this includes compound statements, G0 T0, and simple variable
   1.258 +assignments. The third is continuations, which encompasses the distinction between statements and expressions, escape operators (such as Landin's J-
   1.259 +operator [Landin 65] and Reynold's escape expression [Reynolds 72]). and fluid
   1.260 +(dynamically bound) variables. The fourth is Parameter Passing Mechanisms, such
   1.261 +as ALGOL call—by-name and FORTRAN call-by-location.
   1.262 +Some of the models presented here are already well-known, particularly
   1.263 +those for G0 T0 and assignment. [McCarthy 60] [Landin 65] [Reynolds 72]
   1.264 +Those for escape operators, fluid variables, and call-by-need with side
   1.265 +effects are new.
   1.266 +</p>
   1.267 +</div>
   1.268 +
   1.269 +<div id="outline-container-2-1" class="outline-3">
   1.270 +<h3 id="sec-2-1"><span class="section-number-3">2.1</span> Simple Loops </h3>
   1.271 +<div class="outline-text-3" id="text-2-1">
   1.272 +
   1.273 +<p>By <i>simple loops</i> we mean constructs which enable programs to execute the
   1.274 +same piece of code repeatedly in a controlled manner. Variables may be made
   1.275 +to take on different values during each repetition, and the number of
   1.276 +repetitions may depend on data given to the program.
   1.277 +</p>
   1.278 +</div>
   1.279 +
   1.280 +<div id="outline-container-2-1-1" class="outline-4">
   1.281 +<h4 id="sec-2-1-1"><span class="section-number-4">2.1.1</span> Simple Recursion </h4>
   1.282 +<div class="outline-text-4" id="text-2-1-1">
   1.283 +
   1.284 +<p>One of the easiest ways to produce a looping control structure is to
   1.285 +use a recursive function, one which calls itself to perform a subcomputation.
   1.286 +For example, the familiar factorial function may be written recursively in
   1.287 +ALGOL: '
   1.288 +</p>
   1.289 +
   1.290 +
   1.291 +<pre class="src src-algol">integer procedure fact(n) value n: integer n:
   1.292 +fact := if n=0 then 1 else n*fact(n-1);
   1.293 +
   1.294 +</pre>
   1.295 +
   1.296 +
   1.297 +
   1.298 +
   1.299 +<p>
   1.300 +The invocation <code>fact(n)</code> computes the product of the integers from 1 to n using
   1.301 +the identity n!=n(n-1)! (n&gt;0). If \(n\) is zero, 1 is returned; otherwise <code>fact</code>:
   1.302 +calls itself recursively to compute \((n-1)!\) , then multiplies the result by \(n\)
   1.303 +and returns it.
   1.304 +</p>
   1.305 +<p>
   1.306 +This same function may be written in Clojure as follows:
   1.307 +</p>
   1.308 +
   1.309 +
   1.310 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">ns</span> categorical.imperative)
   1.311 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fact</span>[n]
   1.312 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">=</span> n 0) 1 (<span style="color: #8cd0d3;">*</span> n (fact (<span style="color: #8cd0d3;">dec</span> n))))
   1.313 +)
   1.314 +
   1.315 +</pre>
   1.316 +
   1.317 +
   1.318 +
   1.319 +
   1.320 +
   1.321 +<p>
   1.322 +Clojure does not require an assignment to the ``variable'' fan: to return a value
   1.323 +as ALGOL does. The IF primitive is the ALGOL if-then-else rendered in LISP
   1.324 +syntax. Note that the arithmetic primitives are prefix operators in SCHEME.
   1.325 +</p>
   1.326 +</div>
   1.327 +
   1.328 +</div>
   1.329 +
   1.330 +<div id="outline-container-2-1-2" class="outline-4">
   1.331 +<h4 id="sec-2-1-2"><span class="section-number-4">2.1.2</span> Iteration </h4>
   1.332 +<div class="outline-text-4" id="text-2-1-2">
   1.333 +
   1.334 +<p>There are many other ways to compute factorial. One important way is
   1.335 +through the use of <i>iteration</i>.
   1.336 +A comon iterative construct is the DO loop. The most general form we
   1.337 +have seen in any programming language is the MacLISP DO [Moon 74]. It permits
   1.338 +the simultaneous initialization of any number of control variables and the
   1.339 +simultaneous stepping of these variables by arbitrary functions at each
   1.340 +iteration step. The loop is terminated by an arbitrary predicate, and an
   1.341 +arbitrary value may be returned. The DO loop may have a body, a series of
   1.342 +expressions executed for effect on each iteration. A version of the MacLISP
   1.343 +DO construct has been adopted in SCHEME.
   1.344 +</p>
   1.345 +<p>
   1.346 +The general form of a SCHEME DO is:
   1.347 +</p>
   1.348 +
   1.349 +
   1.350 +<pre class="src src-nothing">(DO ((&lt;var1&gt; (init1&gt; &lt;stepl&gt;)
   1.351 +((var2&gt; &lt;init2&gt; &lt;step2&gt;)
   1.352 +(&lt;varn&gt; &lt;intn&gt; (stepn&gt;))
   1.353 +(&lt;pred&gt; (value&gt;)
   1.354 +(optional body&gt;)
   1.355 +
   1.356 +</pre>
   1.357 +
   1.358 +
   1.359 +
   1.360 +<p>
   1.361 +The semantics of this are that the variables are bound and initialized to the
   1.362 +values of the &lt;initi&gt; expressions, which must all be evaluated in the
   1.363 +environment outside the D0; then the predicate &lt;pred&gt; is evaluated in the new
   1.364 +environment, and if TRUE, the (value) is evaluated and returned. Otherwise
   1.365 +the (optional body) is evaluated, then each of the steppers &lt;stepi&gt; is
   1.366 +evaluated in the current environment, all the variables made to have the
   1.367 +results as their values, the predicate evaluated again, and so on.
   1.368 +Using D0 loops in both ALGOL and SCHEME, we may express FACT by means
   1.369 +of iteration.
   1.370 +</p>
   1.371 +
   1.372 +
   1.373 +<pre class="src src-algol">integer procedure fact(n); value n; integer n:
   1.374 +begin
   1.375 +integer m, ans;
   1.376 +ans := 1;
   1.377 +for m := n step -l until 0 do ans := m*ans;
   1.378 +fact := ans;
   1.379 +end;
   1.380 +
   1.381 +</pre>
   1.382 +
   1.383 +
   1.384 +
   1.385 +
   1.386 +
   1.387 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
   1.388 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fact-do</span>[n]
   1.389 +)
   1.390 +
   1.391 +</pre>
   1.392 +
   1.393 +
   1.394 +
   1.395 +
   1.396 +<p>
   1.397 +Note that the SCHEME D0 loop in FACT has no body &ndash; the stepping functions do
   1.398 +all the work. The ALGOL DO loop has an assignment in its body; because an
   1.399 +ALGOL DO loop can step only one variable, we need the assignment to step the
   1.400 +the variable "manually'.
   1.401 +In reality the SCHEME DO construct is not a primitive; it is a macro
   1.402 +which expands into a function which performs the iteration by tail—recursion.
   1.403 +Consider the following definition of FACT in SCHEME. Although it appears to
   1.404 +be recursive, since it "calls itself", it is entirely equivalent to the DO
   1.405 +loop given above, for it is the code that the DO macro expands into! It
   1.406 +captures the essence of our intuitive notion of iteration, because execution
   1.407 +of this program will not produce internal structures (e.g. stacks or variable
   1.408 +bindings) which increase in size with the number of iteration steps.
   1.409 +</p>
   1.410 +
   1.411 +
   1.412 +
   1.413 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
   1.414 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fact-do-expand</span>[n]
   1.415 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [fact1
   1.416 +        (<span style="color: #8cd0d3;">fn</span>[m ans]
   1.417 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? m) ans
   1.418 +              (<span style="color: #f0dfaf; font-weight: bold;">recur</span> (<span style="color: #8cd0d3;">dec</span> m) (<span style="color: #8cd0d3;">*</span> m ans))))]
   1.419 +    (fact1 n 1)))
   1.420 +
   1.421 +</pre>
   1.422 +
   1.423 +
   1.424 +
   1.425 +
   1.426 +<p>
   1.427 +From this we can infer a general way to express iterations in SCHEME in
   1.428 +a manner isomorphic to the HacLISP D0. The expansion of the general D0 loop
   1.429 +</p>
   1.430 +
   1.431 +
   1.432 +<pre class="src src-nothing">(DO ((&lt;varl&gt; &lt;init1&gt; &lt;step1&gt;)
   1.433 +(&lt;var2&gt; (init2) &lt;step2&gt;)
   1.434 +...
   1.435 +(&lt;varn&gt; &lt;initn&gt; &lt;stepn&gt;))
   1.436 +(&lt;pred&gt; &lt;va1ue&gt;)
   1.437 +&lt;body&gt;)
   1.438 +
   1.439 +</pre>
   1.440 +
   1.441 +
   1.442 +
   1.443 +<p>
   1.444 +is this:
   1.445 +</p>
   1.446 +
   1.447 +
   1.448 +<pre class="src src-nothing">(let [doloop
   1.449 +(fn [dummy &lt;var1&gt; &lt;var2&gt; ... &lt;varn&gt;)
   1.450 +(if &lt;pred&gt; &lt;value&gt;
   1.451 +(recur &lt;body&gt; &lt;step1&gt; &lt;step2&gt; ... &lt;stepn&gt;)))]
   1.452 +
   1.453 +(doloop nil &lt;init1&gt; &lt;init2&gt; ... &lt;initn&gt;))
   1.454 +
   1.455 +</pre>
   1.456 +
   1.457 +
   1.458 +
   1.459 +<p>
   1.460 +The identifiers <code>doloop</code> and <code>dummy</code> are chosen so as not to conflict with any
   1.461 +other identifiers in the program.
   1.462 +Note that, unlike most implementations of D0, there are no side effects
   1.463 +in the steppings of the iteration variables. D0 loops are usually modelled
   1.464 +using assignment statements. For example:
   1.465 +</p>
   1.466 +
   1.467 +
   1.468 +<pre class="src src-nothing">for r :1 0 step b until c do &lt;statement&gt;;
   1.469 +
   1.470 +</pre>
   1.471 +
   1.472 +
   1.473 +
   1.474 +
   1.475 +<p>
   1.476 +can be modelled as follows: [Naur 63]
   1.477 +</p>
   1.478 +
   1.479 +
   1.480 +<pre class="src src-nothing">begin
   1.481 +x := a;
   1.482 +L: if (x-c)*sign(n) &gt; 0 then go to Endloop;
   1.483 +&lt;statement&gt;;
   1.484 +x := x+b;
   1.485 +go to L:
   1.486 +Endloop:
   1.487 +end;
   1.488 +
   1.489 +</pre>
   1.490 +
   1.491 +
   1.492 +
   1.493 +<p>
   1.494 +Later we will see how such assignment statements can in general be
   1.495 +modelled without using side effects.
   1.496 +</p>
   1.497 +</div>
   1.498 +</div>
   1.499 +</div>
   1.500 +
   1.501 +</div>
   1.502 +
   1.503 +<div id="outline-container-3" class="outline-2">
   1.504 +<h2 id="sec-3"><span class="section-number-2">3</span> Imperative Programming </h2>
   1.505 +<div class="outline-text-2" id="text-3">
   1.506 +
   1.507 +<p>Lambda calculus (and related languages, such as ``pure LISP'') is often
   1.508 +used for modelling the applicative constructs of programming languages.
   1.509 +However, they are generally thought of as inappropriate for modelling
   1.510 +imperative constructs. In this section we show how imperative constructs may
   1.511 +be modelled by applicative SCHEME constructs.
   1.512 +</p>
   1.513 +</div>
   1.514 +
   1.515 +<div id="outline-container-3-1" class="outline-3">
   1.516 +<h3 id="sec-3-1"><span class="section-number-3">3.1</span> Compound Statements </h3>
   1.517 +<div class="outline-text-3" id="text-3-1">
   1.518 +
   1.519 +<p>The simplest kind of imperative construct is the statement sequencer,
   1.520 +for example the compound statement in ALGOL:
   1.521 +</p>
   1.522 +
   1.523 +
   1.524 +<pre class="src src-algol">begin
   1.525 +S1;
   1.526 +S2;
   1.527 +end
   1.528 +
   1.529 +</pre>
   1.530 +
   1.531 +
   1.532 +
   1.533 +
   1.534 +<p>
   1.535 +This construct has two interesting properties:
   1.536 +</p><ul>
   1.537 +<li>(1) It performs statement S1 before S2, and so may be used for
   1.538 +  sequencing.
   1.539 +</li>
   1.540 +<li>(2) S1 is useful only for its side effects. (In ALGOL, S2 must also
   1.541 +  be a statement, and so is also useful only for side effects, but
   1.542 +  other languages have compound expressions containing a statement
   1.543 +  followed by an expression.)
   1.544 +</li>
   1.545 +</ul>
   1.546 +
   1.547 +
   1.548 +<p>
   1.549 +The ALGOL compound statement may actually contain any number of statements,
   1.550 +but such statements can be expressed as a series of nested two-statement
   1.551 +compounds. That is:
   1.552 +</p>
   1.553 +
   1.554 +
   1.555 +<pre class="src src-algol">begin
   1.556 +S1;
   1.557 +S2;
   1.558 +...
   1.559 +Sn-1;
   1.560 +Sn;
   1.561 +end
   1.562 +
   1.563 +</pre>
   1.564 +
   1.565 +
   1.566 +
   1.567 +<p>
   1.568 +is equivalent to:
   1.569 +</p>
   1.570 +
   1.571 +
   1.572 +
   1.573 +<pre class="src src-algol">begin
   1.574 +S1;
   1.575 +begin
   1.576 +S2;
   1.577 +begin
   1.578 +...
   1.579 +
   1.580 +begin
   1.581 +Sn-1;
   1.582 +Sn;
   1.583 +end;
   1.584 +end;
   1.585 +end:
   1.586 +end
   1.587 +
   1.588 +</pre>
   1.589 +
   1.590 +
   1.591 +
   1.592 +
   1.593 +<p>
   1.594 +It is not immediately apparent that this sequencing can be expressed in a
   1.595 +purely applicative language. We can, however, take advantage of the implicit
   1.596 +sequencing of applicative order evaluation. Thus, for example, we may write a
   1.597 +two-statement sequence as follows:
   1.598 +</p>
   1.599 +
   1.600 +
   1.601 +
   1.602 +<pre class="src src-clojure">((<span style="color: #8cd0d3;">fn</span>[dummy] S2) S1)
   1.603 +
   1.604 +</pre>
   1.605 +
   1.606 +
   1.607 +
   1.608 +
   1.609 +<p>
   1.610 +where <code>dummy</code> is an identifier not used in S2. From this it is
   1.611 +manifest that the value of S1 is ignored, and so is useful only for
   1.612 +side effects. (Note that we did not claim that S1 is expressed in a
   1.613 +purely applicative language, but only that the sequencing can be so
   1.614 +expressed.) From now on we will use the form <code>(BLOCK S1 S2)</code> as an
   1.615 +abbreviation for this expression, and <code>(BLOCK S1 S2...Sn-1 Sn)</code> as an
   1.616 +abbreviation for 
   1.617 +</p>
   1.618 +
   1.619 +
   1.620 +
   1.621 +<pre class="src src-algol">(BLOCK S1 (BLOCK S2 (BLOCK ... (BLOCK Sn-1 Sn)...))) 
   1.622 +
   1.623 +</pre>
   1.624 +
   1.625 +
   1.626 +
   1.627 +
   1.628 +</div>
   1.629 +
   1.630 +</div>
   1.631 +
   1.632 +<div id="outline-container-3-2" class="outline-3">
   1.633 +<h3 id="sec-3-2"><span class="section-number-3">3.2</span> 2.2. The G0 TO Statement </h3>
   1.634 +<div class="outline-text-3" id="text-3-2">
   1.635 +
   1.636 +
   1.637 +<p>
   1.638 +A more general imperative structure is the compound statement with
   1.639 +labels and G0 T0s. Consider the following code fragment due to
   1.640 +Jacopini, taken from Knuth: [Knuth 74] 
   1.641 +</p>
   1.642 +
   1.643 +
   1.644 +<pre class="src src-algol">begin 
   1.645 +L1: if B1 then go to L2; S1;
   1.646 +    if B2 then go to L2; S2;
   1.647 +    go to L1;
   1.648 +L2: S3;
   1.649 +
   1.650 +</pre>
   1.651 +
   1.652 +
   1.653 +
   1.654 +
   1.655 +<p>
   1.656 +It is perhaps surprising that this piece of code can be <i>syntactically</i>
   1.657 +transformed into a purely applicative style. For example, in SCHEME we
   1.658 +could write:
   1.659 +</p>
   1.660 +
   1.661 +
   1.662 +
   1.663 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
   1.664 +(<span style="color: #f0dfaf; font-weight: bold;">let</span>
   1.665 +    [L1 (<span style="color: #8cd0d3;">fn</span>[]
   1.666 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> B1 (L2) (<span style="color: #f0dfaf; font-weight: bold;">do</span> S1
   1.667 +                          (<span style="color: #f0dfaf; font-weight: bold;">if</span> B2 (L2) (<span style="color: #f0dfaf; font-weight: bold;">do</span> S2 (L1))))))
   1.668 +     L2 (<span style="color: #8cd0d3;">fn</span>[] S3)]
   1.669 +  (L1))
   1.670 +
   1.671 +</pre>
   1.672 +
   1.673 +
   1.674 +
   1.675 +
   1.676 +<p>
   1.677 +As with the D0 loop, this transformation depends critically on SCHEME's
   1.678 +treatment of tail-recursion and on lexical scoping of variables. The labels
   1.679 +are names of functions of no arguments. In order to ‘go to" the labeled code,
   1.680 +we merely call the function named by that label.
   1.681 +</p>
   1.682 +</div>
   1.683 +
   1.684 +</div>
   1.685 +
   1.686 +<div id="outline-container-3-3" class="outline-3">
   1.687 +<h3 id="sec-3-3"><span class="section-number-3">3.3</span> 2.3. Simple Assignment </h3>
   1.688 +<div class="outline-text-3" id="text-3-3">
   1.689 +
   1.690 +<p>Of course, all this sequencing of statements is useless unless the
   1.691 +statements have side effects. An important side effect is assignment. For
   1.692 +example, one often uses assignment to place intermediate results in a named
   1.693 +location (i.e. a variable) so that they may be used more than once later
   1.694 +without recomputing them:
   1.695 +</p>
   1.696 +
   1.697 +
   1.698 +
   1.699 +<pre class="src src-algol">begin
   1.700 +real a2, sqrtdisc;
   1.701 +a2 := 2*a;
   1.702 +sqrtdisc := sqrt(b^2 - 4*a*c);
   1.703 +root1 := (- b + sqrtdisc) / a2;
   1.704 +root2 := (- b - sqrtdisc) / a2;
   1.705 +print(root1);
   1.706 +print(root2);
   1.707 +print(root1 + root2);
   1.708 +end
   1.709 +
   1.710 +</pre>
   1.711 +
   1.712 +
   1.713 +
   1.714 +
   1.715 +<p>
   1.716 +It is well known that such naming of intermediate results may be accomplished
   1.717 +by calling a function and binding the formal parameter variables to the
   1.718 +results: 
   1.719 +</p>
   1.720 +
   1.721 +
   1.722 +
   1.723 +<pre class="src src-clojure">(<span style="color: #8cd0d3;">fn</span> [a2 sqrtdisc]
   1.724 +  ((<span style="color: #8cd0d3;">fn</span>[root1 root2]
   1.725 +    (<span style="color: #f0dfaf; font-weight: bold;">do</span> (<span style="color: #8cd0d3;">println</span> root1)
   1.726 +        (<span style="color: #8cd0d3;">println</span> root2)
   1.727 +        (<span style="color: #8cd0d3;">println</span> (<span style="color: #8cd0d3;">+</span> root1 root2))))
   1.728 +  (<span style="color: #8cd0d3;">/</span> (<span style="color: #8cd0d3;">+</span> (<span style="color: #8cd0d3;">-</span> b) sqrtdisc) a2)
   1.729 +  (<span style="color: #8cd0d3;">/</span> (<span style="color: #8cd0d3;">-</span> (<span style="color: #8cd0d3;">-</span> b) sqrtdisc) a2))
   1.730 +
   1.731 +  (<span style="color: #8cd0d3;">*</span> 2 a)
   1.732 +  (sqrt (<span style="color: #8cd0d3;">-</span> (<span style="color: #8cd0d3;">*</span> b b) (<span style="color: #8cd0d3;">*</span> 4 a c))))
   1.733 +
   1.734 +</pre>
   1.735 +
   1.736 +
   1.737 +
   1.738 +<p>
   1.739 +This technique can be extended to handle all simple variable assignments which
   1.740 +appear as statements in blocks, even if arbitrary G0 T0 statements also appear
   1.741 +in such blocks. {Note Mccarthywins}
   1.742 +</p>
   1.743 +<p>
   1.744 +For example, here is a program which uses G0 TO statements in the form
   1.745 +presented before; it determines the parity of a non-negative integer by
   1.746 +counting it down until it reaches zero.
   1.747 +</p>
   1.748 +
   1.749 +
   1.750 +
   1.751 +<pre class="src src-algol">begin
   1.752 +L1: if a = 0 then begin parity := 0; go to L2; end;
   1.753 +    a := a - 1;
   1.754 +    if a = 0 then begin parity := 1; go to L2; end;
   1.755 +    a := a - 1;
   1.756 +    go to L1;
   1.757 +L2: print(parity);
   1.758 +
   1.759 +</pre>
   1.760 +
   1.761 +
   1.762 +
   1.763 +
   1.764 +<p>
   1.765 +This can be expressed in SCHEME:
   1.766 +</p>
   1.767 +
   1.768 +
   1.769 +
   1.770 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">let</span>
   1.771 +    [L1 (<span style="color: #8cd0d3;">fn</span> [a parity]
   1.772 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? a) (L2 a 0)
   1.773 +              (L3 (<span style="color: #8cd0d3;">dec</span> a) parity)))
   1.774 +     L3 (<span style="color: #8cd0d3;">fn</span> [a parity]
   1.775 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? a) (L2 a 1)
   1.776 +              (L1 (<span style="color: #8cd0d3;">dec</span> a) parity)))
   1.777 +     L2 (<span style="color: #8cd0d3;">fn</span> [a parity]
   1.778 +          (<span style="color: #8cd0d3;">println</span> parity))]
   1.779 +  (L1 a parity))
   1.780 +
   1.781 +</pre>
   1.782 +
   1.783 +
   1.784 +
   1.785 +
   1.786 +<p>
   1.787 +The trick is to pass the set of variables which may be altered as arguments to
   1.788 +the label functions. {Note Flowgraph} It may be necessary to introduce new
   1.789 +labels (such as L3) so that an assignment may be transformed into the binding
   1.790 +for a function call. At worst, one may need as many labels as there are
   1.791 +statements (not counting the eliminated assignment and GO TO statements).
   1.792 +</p>
   1.793 +</div>
   1.794 +
   1.795 +</div>
   1.796 +
   1.797 +<div id="outline-container-3-4" class="outline-3">
   1.798 +<h3 id="sec-3-4"><span class="section-number-3">3.4</span> Compound Expressions ' </h3>
   1.799 +<div class="outline-text-3" id="text-3-4">
   1.800 +
   1.801 +<p>At this point we are almost in a position to model the most general
   1.802 +form of compound statement. In LISP, this is called the 'PROG feature". In
   1.803 +addition to statement sequencing and G0 T0 statements, one can return a <i>value</i>
   1.804 +from a PROG by using the RETURN statement.
   1.805 +</p>
   1.806 +<p>
   1.807 +Let us first consider the simplest compound statement, which in SCHEME
   1.808 +we call BLOCK. Recall that
   1.809 +<code>(BLOCK s1 sz)</code> is defined to be <code>((lambda (dummy) s2) s1)</code>
   1.810 +</p>
   1.811 +<p>
   1.812 +Notice that this not only performs Sl before S2, but also returns the value of
   1.813 +S2. Furthermore, we defined <code>(BLOCK S1 S2 ... Sn)</code> so that it returns the value
   1.814 +of <code>Sn</code>. Thus BLOCK may be used as a compound expression, and models a LISP
   1.815 +PROGN, which is a PROG with no G0 T0 statements and an implicit RETURN of the
   1.816 +last ``statement'' (really an expression).
   1.817 +</p>
   1.818 +<p>
   1.819 +Host LISP compilers compile D0 expressions by macro-expansion. We have
   1.820 +already seen one way to do this in SCHEME using only variable binding. A more
   1.821 +common technique is to expand the D0 into a PROG, using variable assignments
   1.822 +instead of bindings. Thus the iterative factorial program:
   1.823 +</p>
   1.824 +
   1.825 +
   1.826 +
   1.827 +<pre class="src src-clojure">(oarxnz FACT .
   1.828 +(LAMaoA (n) .
   1.829 +(D0 ((M N (<span style="color: #8cd0d3;">-</span> H 1))
   1.830 +(Ans 1 (<span style="color: #8cd0d3;">*</span> M Ans)))
   1.831 +((<span style="color: #8cd0d3;">-</span> H 0) A<span style="color: #cc9393;">"$))))</span>
   1.832 +
   1.833 +</pre>
   1.834 +
   1.835 +
   1.836 +
   1.837 +
   1.838 +<p>
   1.839 +would expand into:
   1.840 +</p>
   1.841 +
   1.842 +
   1.843 +
   1.844 +<pre class="src src-clojure">(DEFINE FACT
   1.845 +. (LAMeoA (M)
   1.846 +(PRO6 (M Ans)
   1.847 +(sszro M n
   1.848 +Ans 1) ~
   1.849 +LP (tr (<span style="color: #8cd0d3;">-</span> M 0) (RETURN Ans))
   1.850 +(ssero M (<span style="color: #8cd0d3;">-</span> n 1)
   1.851 +Ans (' M Ans))
   1.852 +(60 LP))))
   1.853 +
   1.854 +</pre>
   1.855 +
   1.856 +
   1.857 +
   1.858 +
   1.859 +<p>
   1.860 +where SSETQ is a simultaneous multiple assignment operator. (SSETQ is not a
   1.861 +SCHEME (or LISP) primitive. It can be defined in terms of a single assignment
   1.862 +operator, but we are more interested here in RETURN than in simultaneous
   1.863 +assignment. The SSETQ's will all be removed anyway and modelled by lambda
   1.864 +binding.) We can apply the same technique we used before to eliminate G0 T0
   1.865 +statements and assignments from compound statements:
   1.866 +</p>
   1.867 +
   1.868 +
   1.869 +
   1.870 +<pre class="src src-clojure">(DEFINE FACT
   1.871 +(LAHBOA (I)
   1.872 +(LABELS ((L1 (LAManA (M Ans)
   1.873 +(LP n 1)))
   1.874 +(LP (LAMaoA (M Ans)
   1.875 +(IF (<span style="color: #8cd0d3;">-</span> M o) (nztunn Ans)
   1.876 +(&#163;2 H An$))))
   1.877 +(L2 (LAMaoA (M An )
   1.878 +(LP (<span style="color: #8cd0d3;">-</span> <span style="color: #cc9393;">" 1) (' H &#64258;N$)))))</span>
   1.879 +<span style="color: #e37170; background-color: #332323;">(</span><span style="color: #cc9393;">L1 NIL NlL))))</span>
   1.880 +
   1.881 +</pre>
   1.882 +
   1.883 +
   1.884 +<p>
   1.885 + clojure
   1.886 +</p>
   1.887 +<p>
   1.888 +We still haven't done anything about RETURN. Let's see&hellip;
   1.889 +</p><ul>
   1.890 +<li>==&gt; the value of (FACT 0) is the value of (Ll NIL NIL)
   1.891 +</li>
   1.892 +<li>==&gt; which is the value of (LP 0 1)
   1.893 +</li>
   1.894 +<li>==&gt; which is the value of (IF (= 0 0) (RETURN 1) (L2 0 1))
   1.895 +</li>
   1.896 +<li>==&gt; which is the value of (RETURN 1) 
   1.897 +</li>
   1.898 +</ul>
   1.899 +
   1.900 +
   1.901 +<p>
   1.902 +Notice that if RETURN were the <i>identity function</i> (LAMBDA (X) X), we would get the right answer. This is in fact a
   1.903 +general truth: if we Just replace a call to RETURN with its argument, then
   1.904 +our old transformation on compound statements extends to general compound
   1.905 +expressions, i.e. PROG.
   1.906 +</p>
   1.907 +</div>
   1.908 +</div>
   1.909 +
   1.910 +</div>
   1.911 +
   1.912 +<div id="outline-container-4" class="outline-2">
   1.913 +<h2 id="sec-4"><span class="section-number-2">4</span> Continuations </h2>
   1.914 +<div class="outline-text-2" id="text-4">
   1.915 +
   1.916 +<p>Up to now we have thought of SCHEME's LAMBDA expressions as functions,
   1.917 +and of a combination such as <code>(G (F X Y))</code> as meaning ``apply the function F to
   1.918 +the values of X and Y, and return a value so that the function G can be
   1.919 +applied and return a value &hellip;'' But notice that we have seldom used LAMBDA
   1.920 +expressions as functions. Rather, we have used them as control structures and
   1.921 +environment modifiers. For example, consider the expression:
   1.922 +<code>(BLOCK (PRINT 3) (PRINT 4))</code>
   1.923 +</p>
   1.924 +<p>
   1.925 +This is defined to be an abbreviation for:
   1.926 +<code>((LAMBDA  (DUMMY) (PRINT 4)) (PRINT 3))</code>
   1.927 +</p>
   1.928 +<p>
   1.929 +We do not care about the value of this BLOCK expression; it follows that we
   1.930 +do not care about the value of the <code>(LAMBDA (DUMMY) ...)</code>. We are not using
   1.931 +LAMBDA as a function at all.
   1.932 +</p>
   1.933 +<p>
   1.934 +It is possible to write useful programs in terms of LAHBDA expressions
   1.935 +in which we never care about the value of <i>any</i> lambda expression. We have
   1.936 +already demonstrated how one could represent any "FORTRAN" program in these
   1.937 +terms: all one needs is PROG (with G0 and SETQ), and PRINT to get the answers
   1.938 +out. The ultimate generalization of this imperative programing style is
   1.939 +<i>continuation-passing</i>. (Note Churchwins} .
   1.940 +</p>
   1.941 +
   1.942 +</div>
   1.943 +
   1.944 +<div id="outline-container-4-1" class="outline-3">
   1.945 +<h3 id="sec-4-1"><span class="section-number-3">4.1</span> Continuation-Passing Recursion </h3>
   1.946 +<div class="outline-text-3" id="text-4-1">
   1.947 +
   1.948 +<p>Consider the following alternative definition of FACT. It has an extra
   1.949 +argument, the continuation, which is a function to call with the answer, when
   1.950 +we have it, rather than return a value
   1.951 +</p>
   1.952 +
   1.953 +
   1.954 +
   1.955 +<pre class="src src-algol.">procedure Inc!(n, c); value n, c;
   1.956 +integer n: procedure c(integer value);
   1.957 +if n-=0 then c(l) else
   1.958 +begin
   1.959 +procedure l(!mp(d) value a: integer a;
   1.960 +c(mm);
   1.961 +Iacl(n-1, romp):
   1.962 +end;
   1.963 +
   1.964 +</pre>
   1.965 +
   1.966 +
   1.967 +
   1.968 +
   1.969 +
   1.970 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
   1.971 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fact-cps</span>[n k]
   1.972 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? n) (k 1)
   1.973 +      (<span style="color: #f0dfaf; font-weight: bold;">recur</span> (<span style="color: #8cd0d3;">dec</span> n) (<span style="color: #8cd0d3;">fn</span>[a] (k (<span style="color: #8cd0d3;">*</span> n a))))))
   1.974 +
   1.975 +</pre>
   1.976 +
   1.977 +
   1.978 +<p>
   1.979 + clojure
   1.980 +It is fairly clumsy to use this version of‘ FACT in ALGOL; it is necessary to
   1.981 +do something like this:
   1.982 +</p>
   1.983 +
   1.984 +
   1.985 +
   1.986 +<pre class="src src-algol">begin
   1.987 +integer ann
   1.988 +procedure :emp(x); value 2:; integer x;
   1.989 +ans :1 x;
   1.990 +]'act(3. temp);
   1.991 +comment Now the variable <span style="color: #cc9393;">"am"</span> has 6;
   1.992 +end;
   1.993 +
   1.994 +</pre>
   1.995 +
   1.996 +
   1.997 +
   1.998 +
   1.999 +<p>
  1.1000 +Procedure <code>fact</code> does not return a value, nor does <code>temp</code>; we must use a side
  1.1001 +effect to get the answer out.
  1.1002 +</p>
  1.1003 +<p>
  1.1004 +<code>FACT</code> is somewhat easier to use in SCHEME. We can call it like an
  1.1005 +ordinary function in SCHEME if we supply an identity function as the second
  1.1006 +argument. For example, <code>(FACT 3 (LAMBDA (X) X))</code> returns 6. Alternatively, we
  1.1007 +could write <code>(FACT 3 (LAHBDA (X) (PRINT X)))</code>; we do not care about the value
  1.1008 +of this, but about what gets printed. A third way to use the value is to
  1.1009 +write
  1.1010 +<code>(FACT 3 (LAMBDA (x) (SQRT x)))</code>
  1.1011 +instead of
  1.1012 +<code>(SQRT (FACT 3 (LAMBDA (x) x)))</code>
  1.1013 +</p>
  1.1014 +<p>
  1.1015 +In either of these cases we care about the value of the continuation given to
  1.1016 +FACT. Thus we care about the value of FACT if and only if we care about the
  1.1017 +value of its continuation!
  1.1018 +</p>
  1.1019 +<p>
  1.1020 +We can redefine other functions to take continuations in the same way.
  1.1021 +For example, suppose we had arithmetic primitives which took continuations; to
  1.1022 +prevent confusion, call the version of "+" which takes a continuation '++",
  1.1023 +etc. Instead of writing
  1.1024 +<code>(- (+ B Z)(* 4 A C))</code>
  1.1025 +we can write
  1.1026 +</p>
  1.1027 +
  1.1028 +
  1.1029 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
  1.1030 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">enable-continuation</span> <span style="color: #8fb28f;">"Makes f take a continuation as an additional argument."</span>[f]
  1.1031 +  (<span style="color: #8cd0d3;">fn</span>[&amp; args] ((<span style="color: #8cd0d3;">fn</span>[k] (k (<span style="color: #8cd0d3;">apply</span> f (<span style="color: #8cd0d3;">reverse</span> (<span style="color: #8cd0d3;">rest</span> (<span style="color: #8cd0d3;">reverse</span> args)))))) (<span style="color: #8cd0d3;">last</span> args)) ))
  1.1032 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">+&amp;</span> (enable-continuation +))
  1.1033 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">*&amp;</span> (enable-continuation *))
  1.1034 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">-&amp;</span> (enable-continuation -))
  1.1035 +
  1.1036 +
  1.1037 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">quadratic</span>[a b c k]
  1.1038 +(*&amp; b b
  1.1039 +    (<span style="color: #8cd0d3;">fn</span>[x] (*&amp; 4 a c
  1.1040 +               (<span style="color: #8cd0d3;">fn</span>[y]
  1.1041 +                 (-&amp; x y k))))))
  1.1042 +
  1.1043 +</pre>
  1.1044 +
  1.1045 +
  1.1046 +
  1.1047 +
  1.1048 +<p>
  1.1049 +where <code>k</code> is the continuation for the entire expression.
  1.1050 +</p>
  1.1051 +<p>
  1.1052 +This is an obscure way to write an algebraic expression, and we would
  1.1053 +not advise writing code this way in general, but continuation-passing brings
  1.1054 +out certain important features of the computation:
  1.1055 +</p><ul>
  1.1056 +<li><sup><a class="footref" name="fnr.1" href="#fn.1">1</a></sup> The operations to be performed appear in the order in which they are
  1.1057 +</li>
  1.1058 +</ul>
  1.1059 +
  1.1060 +<p>performed. In fact, they <i>must</i> be performed in this
  1.1061 +order. Continuation- passing removes the need for the rule about
  1.1062 +left-to-right argument evaluation{Note Evalorder)
  1.1063 +</p><ul>
  1.1064 +<li><sup><a class="footref" name="fnr.2" href="#fn.2">2</a></sup> In the usual applicative expression there are two implicit
  1.1065 +  temporary values: those of <code>(* B B)</code> and <code>(* 4 A C)</code>. The first of
  1.1066 +  these values must be preserved over the computation of the second,
  1.1067 +  whereas the second is used as soon as it is produced. These facts
  1.1068 +  are <i>manifest</i> in the appearance and use of the variable X and Y in
  1.1069 +  the continuation-passing version.  
  1.1070 +</li>
  1.1071 +</ul>
  1.1072 +
  1.1073 +
  1.1074 +<p>
  1.1075 +In short, the continuation-passing version specifies <i>exactly</i> and
  1.1076 +  explicitly what steps are necessary to compute the value of the
  1.1077 +  expression.  One can think of conventional functional application
  1.1078 +  for value as being an abbreviation for the more explicit
  1.1079 +  continuation-passing style. Alternatively, one can think of the
  1.1080 +  interpreter as supplying to each function an implicit default
  1.1081 +  continuation of one argument. This continuation will receive the
  1.1082 +  value of the function as its argument, and then carry on the
  1.1083 +  computation. In an interpreter this implicit continuation is
  1.1084 +  represented by the control stack mechanism for function returns.
  1.1085 +  Now consider what computational steps are implied by: 
  1.1086 +</p>
  1.1087 +<p>
  1.1088 +<code>(LAMBDA (A B C ...) (F X Y Z ...))</code> when we "apply" the LAMBDA
  1.1089 +  expression we have some values to apply it to; we let the names A,
  1.1090 +  B, C &hellip; refer to these values. We then determine the values of X,
  1.1091 +  Y, Z &hellip; and pass these values (along with "the buck",
  1.1092 +  i.e. control!) to the lambda expression F (F is either a lambda
  1.1093 +  expression or a name for one).  Passing control to F is an
  1.1094 +  unconditional transfer. (Note Jrsthack) {Note Hewitthack) Note that
  1.1095 +  we want values from X, Y, Z, &hellip; If these are simple expressions,
  1.1096 +  such as variables, constants, or LAMBDA expressions, the evaluation
  1.1097 +  process is trivial, in that no temporary storage is required. In
  1.1098 +  pure continuation-passing style, all evaluations are trivial: no
  1.1099 +  combination is nested within another, and therefore no ‘hidden
  1.1100 +  temporaries" are required.  But if X is a combination, say (G P Q),
  1.1101 +  then we want to think of G as a function, because we want a value
  1.1102 +  from it, and we will need an implicit temporary place to keep the
  1.1103 +  result while evaluating Y and Z. (An interpreter usually keeps these
  1.1104 +  temporary places in the control stack!) On the other hand, we do not
  1.1105 +  necessarily need a value from F. This is what we mean by tail-
  1.1106 +  recursion: F is called tail-recursively, whereas G is not. A better
  1.1107 +  name for tail-recursion would be "tail-transfer", since no real
  1.1108 +  recursion is implied.  This is why we have made such a fuss about
  1.1109 +  tail-recursion: it can be used for transfer of control without
  1.1110 +  making any commitment about whether the expression expected to
  1.1111 +  return a value. Thus it can be used to model statement-like control
  1.1112 +  structures. Put another way, tail—recursion does not require a
  1.1113 +  control stack as nested recursion does. In our models of iteration
  1.1114 +  and imperative style all the LAMBDA expressions used for control (to
  1.1115 +  simulate GO statements, for example) are called in tail-recursive
  1.1116 +  fashion.
  1.1117 +</p>
  1.1118 +</div>
  1.1119 +
  1.1120 +</div>
  1.1121 +
  1.1122 +<div id="outline-container-4-2" class="outline-3">
  1.1123 +<h3 id="sec-4-2"><span class="section-number-3">4.2</span> Escape Expressions </h3>
  1.1124 +<div class="outline-text-3" id="text-4-2">
  1.1125 +
  1.1126 +<p>Reynolds [Reynolds 72] defines the construction
  1.1127 += escape x in r =
  1.1128 +</p>
  1.1129 +<p>
  1.1130 +to evaluate the expression \(r\) in an environment such that the variable \(x\) is
  1.1131 +bound to an escape function. If the escape function is never applied, then
  1.1132 +the value of the escape expression is the value of \(r\). If the escape function
  1.1133 +is applied to an argument \(a\), however, then evaluation of \(r\) is aborted and the
  1.1134 +escape expression returns \(a\). {Note J-operator} (Reynolds points out that
  1.1135 +this definition is not quite accurate, since the escape function may be called
  1.1136 +even after the escape expression has returned a value; if this happens, it
  1.1137 +“returns again"!)
  1.1138 +</p>
  1.1139 +<p>
  1.1140 +As an example of the use of an escape expression, consider this
  1.1141 +procedure to compute the harmonic mean of an array of numbers. If any of the
  1.1142 +numbers is zero, we want the answer to be zero. We have a function hannaunl
  1.1143 +which will sum the reciprocals of numbers in an array, or call an escape
  1.1144 +function with zero if any of the numbers is zero. (The implementation shown
  1.1145 +here is awkward because ALGOL requires that a function return its value by
  1.1146 +assignment.)
  1.1147 +</p>
  1.1148 +
  1.1149 +
  1.1150 +<pre class="src src-algol">begin
  1.1151 +real procedure Imrmsum(a, n. escfun)&#167; p
  1.1152 +real array at integer n; real procedure esciun(real);
  1.1153 +begin
  1.1154 +real sum;
  1.1155 +sum := 0;
  1.1156 +for i :1 0 until n-l do
  1.1157 +begin
  1.1158 +if a[i]=0 then cscfun(0);
  1.1159 +sum :1 sum &#162; I/a[i];
  1.1160 +enm
  1.1161 +harmsum SI sum;
  1.1162 +end: .
  1.1163 +real array b[0:99]:
  1.1164 +print(escape x in I00/hm-m.mm(b, 100, x));
  1.1165 +end
  1.1166 +
  1.1167 +</pre>
  1.1168 +
  1.1169 +
  1.1170 +
  1.1171 +
  1.1172 +<p>
  1.1173 +If harmsum exits normally, the number of elements is divided by the sum and
  1.1174 +printed. Otherwise, zero is returned from the escape expression and printed
  1.1175 +without the division ever occurring.
  1.1176 +This program can be written in SCHEME using the built-in escape
  1.1177 +operator <code>CATCH</code>:
  1.1178 +</p>
  1.1179 +
  1.1180 +
  1.1181 +
  1.1182 +<pre class="src src-clojure">abc
  1.1183 +
  1.1184 +</pre>
  1.1185 +
  1.1186 +
  1.1187 +
  1.1188 +<div id="footnotes">
  1.1189 +<h2 class="footnotes">Footnotes: </h2>
  1.1190 +<div id="text-footnotes">
  1.1191 +<p class="footnote"><sup><a class="footnum" name="fn.1" href="#fnr.1">1</a></sup> DEFINITION NOT FOUND: 1
  1.1192 +</p>
  1.1193 +
  1.1194 +<p class="footnote"><sup><a class="footnum" name="fn.2" href="#fnr.2">2</a></sup> DEFINITION NOT FOUND: 2
  1.1195 +</p>
  1.1196 +</div>
  1.1197 +</div>
  1.1198 +</div>
  1.1199 +
  1.1200 +</div>
  1.1201 +</div>
  1.1202 +<div id="postamble">
  1.1203 +<p class="date">Date: 2011-07-15 02:49:04 EDT</p>
  1.1204 +<p class="author">Author: Guy Lewis Steele Jr. and Gerald Jay Sussman</p>
  1.1205 +<p class="creator">Org version 7.6 with Emacs version 23</p>
  1.1206 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  1.1207 +</div>
  1.1208 +</div>
  1.1209 +</body>
  1.1210 +</html>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/categorical/imperative.org	Fri Oct 28 00:03:05 2011 -0700
     2.3 @@ -0,0 +1,772 @@
     2.4 +#+TITLE: LAMBDA: The Ultimate Imperative
     2.5 +#+AUTHOR: Guy Lewis Steele Jr. and Gerald Jay Sussman
     2.6 +
     2.7 +* Abstract 
     2.8 +
     2.9 +We demonstrate how to model the following common programming constructs in
    2.10 +terms of an applicative order language similar to LISP:
    2.11 +- Simple Recursion
    2.12 +- Iteration 
    2.13 +- Compound Statements and Expressions
    2.14 +- GO TO and Assignment
    2.15 +- Continuation—Passing
    2.16 +- Escape Expressions
    2.17 +- Fluid Variables
    2.18 +- Call by Name, Call by Need, and Call by Reference
    2.19 +The models require only (possibly self-referent) lambda application,
    2.20 +conditionals, and (rarely) assignment. No complex data structures such as
    2.21 +stacks are used. The models are transparent, involving only local syntactic
    2.22 +transformations.
    2.23 +Some of these models, such as those for GO TO and assignment, are already well
    2.24 +known, and appear in the work of Landin, Reynolds, and others. The models for
    2.25 +escape expressions, fluid variables, and call by need with side effects are
    2.26 +new. This paper is partly tutorial in intent, gathering all the models
    2.27 +together for purposes of context.
    2.28 +This report describes research done at the Artificial Intelligence Laboratory
    2.29 +of the Massachusetts Institute of Teehnology. Support for the laboratory's
    2.30 +artificial intelligence research is provided in part by the Advanced Research
    2.31 +Projects Agency of the Department of Defense under Office of Naval Research
    2.32 +contract N000l4-75-C-0643.
    2.33 +
    2.34 +* Introduction
    2.35 +
    2.36 + We catalogue a number of common programming constructs. For each
    2.37 +construct we examine "typical" usage in well-known programming languages, and
    2.38 +then capture the essence of the semantics of the construct in terms of a
    2.39 +common meta-language.
    2.40 +The lambda calculus {Note Alonzowins} is often used as such a meta-
    2.41 +language. Lambda calculus offers clean semantics, but it is clumsy because it
    2.42 +was designed to be a minimal language rather than a convenient one. All
    2.43 +lambda calculus "functions" must take exactly one "argument"; the only "data
    2.44 +type" is lambda expressions; and the only "primitive operation‘ is variable‘
    2.45 +substitution. While its utter simplicity makes lambda calculus ideal for
    2.46 +logicians, it is too primitive for use by programmers. The meta-language we
    2.47 +use is a programming language called SCHEME {Note Schemepaper) which is based
    2.48 +on lambda calculus.
    2.49 +SCHEME is a dialect of LISP. [McCarthy 62] It is an expression-
    2.50 +oriented, applicative order, interpreter-based language which allows one to
    2.51 +manipulate programs as data. It differs from most current dialects of LISP in
    2.52 +that it closes all lambda expressions in the environment of their definition
    2.53 +or declaration, rather than in the execution environment. {Note Closures}
    2.54 +This preserves the substitution semantics of lambda calculus, and has the
    2.55 +consequence that all variables are lexically scoped, as in ALGOL. [Naur 63]
    2.56 +Another difference is that SCHEME is implemented in such a way that tail-
    2.57 +recursions execute without net growth of the interpreter stack. {Note
    2.58 +Schemenote} We have chosen to use LISP syntax rather than, say, ALGOL syntax
    2.59 +because we want to treat programs as data for the purpose of describing
    2.60 +transformations on the code. LISP supplies names for the parts of an
    2.61 +executable expression and standard operators for constructing expressions and
    2.62 +extracting their components. The use of LISP syntax makes the structure of
    2.63 +such expressions manifest. We use ALGOL as an expository language, because it
    2.64 +is familiar to many people, but ALGOL is not sufficiently powerful to express
    2.65 +the necessary concepts; in particular, it does not allow functions to return
    2.66 +functions as values. we are thus forced to use a dialect of LISP in many
    2.67 +cases.
    2.68 +We will consider various complex programming language constructs and
    2.69 +show how to model them in terms of only a few simple ones. As far as possible
    2.70 +we will use only three control constructs from SCHEME: LAMBDA expressions, as
    2.71 +in LISP, which are Just functions with lexically scoped free variables;
    2.72 +LABELS, which allows declaration of mutually recursive procedures (Note
    2.73 +Labelsdef}; and IF, a primitive conditional expression. For more complex
    2.74 +modelling we will introduce an assignment primitive (ASET).i We will freely
    2.75 +assume the existence of other comon primitives, such as arithmetic functions.
    2.76 +The constructs we will examine are divided into four broad classes.
    2.77 +The first is sfinph?Lo0pl; this contains simple recursions and iterations, and
    2.78 +an introduction to the notion of continuations. The second is hmponflivo
    2.79 +Connrucls; this includes compound statements, G0 T0, and simple variable
    2.80 +assignments. The third is continuations, which encompasses the distinction between statements and expressions, escape operators (such as Landin's J-
    2.81 +operator [Landin 65] and Reynold's escape expression [Reynolds 72]). and fluid
    2.82 +(dynamically bound) variables. The fourth is Parameter Passing Mechanisms, such
    2.83 +as ALGOL call—by-name and FORTRAN call-by-location.
    2.84 +Some of the models presented here are already well-known, particularly
    2.85 +those for G0 T0 and assignment. [McCarthy 60] [Landin 65] [Reynolds 72]
    2.86 +Those for escape operators, fluid variables, and call-by-need with side
    2.87 +effects are new.
    2.88 +** Simple Loops
    2.89 +By /simple loops/ we mean constructs which enable programs to execute the
    2.90 +same piece of code repeatedly in a controlled manner. Variables may be made
    2.91 +to take on different values during each repetition, and the number of
    2.92 +repetitions may depend on data given to the program.
    2.93 +*** Simple Recursion
    2.94 +One of the easiest ways to produce a looping control structure is to
    2.95 +use a recursive function, one which calls itself to perform a subcomputation.
    2.96 +For example, the familiar factorial function may be written recursively in
    2.97 +ALGOL: '
    2.98 +#+begin_src algol
    2.99 +integer procedure fact(n) value n: integer n:
   2.100 +fact := if n=0 then 1 else n*fact(n-1);
   2.101 +#+end_src
   2.102 +
   2.103 +The invocation =fact(n)= computes the product of the integers from 1 to n using
   2.104 +the identity n!=n(n-1)! (n>0). If $n$ is zero, 1 is returned; otherwise =fact=:
   2.105 +calls itself recursively to compute $(n-1)!$ , then multiplies the result by $n$
   2.106 +and returns it.
   2.107 +
   2.108 +This same function may be written in Clojure as follows:
   2.109 +#+begin_src clojure
   2.110 +(ns categorical.imperative)
   2.111 +(defn fact[n]
   2.112 +  (if (= n 0) 1 (* n (fact (dec n))))
   2.113 +)
   2.114 +#+end_src
   2.115 +
   2.116 +#+results:
   2.117 +: #'categorical.imperative/fact
   2.118 +
   2.119 +Clojure does not require an assignment to the ``variable'' fan: to return a value
   2.120 +as ALGOL does. The IF primitive is the ALGOL if-then-else rendered in LISP
   2.121 +syntax. Note that the arithmetic primitives are prefix operators in SCHEME.
   2.122 +
   2.123 +*** Iteration
   2.124 +There are many other ways to compute factorial. One important way is
   2.125 +through the use of /iteration/.
   2.126 +A comon iterative construct is the DO loop. The most general form we
   2.127 +have seen in any programming language is the MacLISP DO [Moon 74]. It permits
   2.128 +the simultaneous initialization of any number of control variables and the
   2.129 +simultaneous stepping of these variables by arbitrary functions at each
   2.130 +iteration step. The loop is terminated by an arbitrary predicate, and an
   2.131 +arbitrary value may be returned. The DO loop may have a body, a series of
   2.132 +expressions executed for effect on each iteration. A version of the MacLISP
   2.133 +DO construct has been adopted in SCHEME.
   2.134 +
   2.135 +The general form of a SCHEME DO is:
   2.136 +#+begin_src nothing
   2.137 +(DO ((<var1> (init1> <stepl>)
   2.138 +((var2> <init2> <step2>)
   2.139 +(<varn> <intn> (stepn>))
   2.140 +(<pred> (value>)
   2.141 +(optional body>)
   2.142 +#+end_src
   2.143 +The semantics of this are that the variables are bound and initialized to the
   2.144 +values of the <initi> expressions, which must all be evaluated in the
   2.145 +environment outside the D0; then the predicate <pred> is evaluated in the new
   2.146 +environment, and if TRUE, the (value) is evaluated and returned. Otherwise
   2.147 +the (optional body) is evaluated, then each of the steppers <stepi> is
   2.148 +evaluated in the current environment, all the variables made to have the
   2.149 +results as their values, the predicate evaluated again, and so on.
   2.150 +Using D0 loops in both ALGOL and SCHEME, we may express FACT by means
   2.151 +of iteration.
   2.152 +#+begin_src algol
   2.153 +integer procedure fact(n); value n; integer n:
   2.154 +begin
   2.155 +integer m, ans;
   2.156 +ans := 1;
   2.157 +for m := n step -l until 0 do ans := m*ans;
   2.158 +fact := ans;
   2.159 +end;
   2.160 +#+end_src
   2.161 +
   2.162 +#+begin_src clojure
   2.163 +(in-ns 'categorical.imperative)
   2.164 +(defn fact-do[n]
   2.165 +)
   2.166 +#+end_src
   2.167 +
   2.168 +Note that the SCHEME D0 loop in FACT has no body -- the stepping functions do
   2.169 +all the work. The ALGOL DO loop has an assignment in its body; because an
   2.170 +ALGOL DO loop can step only one variable, we need the assignment to step the
   2.171 +the variable "manually'.
   2.172 +In reality the SCHEME DO construct is not a primitive; it is a macro
   2.173 +which expands into a function which performs the iteration by tail—recursion.
   2.174 +Consider the following definition of FACT in SCHEME. Although it appears to
   2.175 +be recursive, since it "calls itself", it is entirely equivalent to the DO
   2.176 +loop given above, for it is the code that the DO macro expands into! It
   2.177 +captures the essence of our intuitive notion of iteration, because execution
   2.178 +of this program will not produce internal structures (e.g. stacks or variable
   2.179 +bindings) which increase in size with the number of iteration steps.
   2.180 +
   2.181 +#+begin_src clojure
   2.182 +(in-ns 'categorical.imperative)
   2.183 +(defn fact-do-expand[n]
   2.184 +  (let [fact1
   2.185 +	(fn[m ans]
   2.186 +	  (if (zero? m) ans
   2.187 +	      (recur (dec m) (* m ans))))]
   2.188 +    (fact1 n 1)))
   2.189 +#+end_src
   2.190 +
   2.191 +From this we can infer a general way to express iterations in SCHEME in
   2.192 +a manner isomorphic to the HacLISP D0. The expansion of the general D0 loop
   2.193 +#+begin_src nothing
   2.194 +(DO ((<varl> <init1> <step1>)
   2.195 +(<var2> (init2) <step2>)
   2.196 +...
   2.197 +(<varn> <initn> <stepn>))
   2.198 +(<pred> <va1ue>)
   2.199 +<body>)
   2.200 +#+end_src
   2.201 +is this:
   2.202 +#+begin_src nothing
   2.203 +(let [doloop
   2.204 +(fn [dummy <var1> <var2> ... <varn>)
   2.205 +(if <pred> <value>
   2.206 +(recur <body> <step1> <step2> ... <stepn>)))]
   2.207 +
   2.208 +(doloop nil <init1> <init2> ... <initn>))
   2.209 +#+end_src
   2.210 +The identifiers =doloop= and =dummy= are chosen so as not to conflict with any
   2.211 +other identifiers in the program.
   2.212 +Note that, unlike most implementations of D0, there are no side effects
   2.213 +in the steppings of the iteration variables. D0 loops are usually modelled
   2.214 +using assignment statements. For example:
   2.215 +#+begin_src nothing
   2.216 +for r :1 0 step b until c do <statement>;
   2.217 +#+end_src
   2.218 +
   2.219 +can be modelled as follows: [Naur 63]
   2.220 +#+begin_src nothing
   2.221 +begin
   2.222 +x := a;
   2.223 +L: if (x-c)*sign(n) > 0 then go to Endloop;
   2.224 +<statement>;
   2.225 +x := x+b;
   2.226 +go to L:
   2.227 +Endloop:
   2.228 +end;
   2.229 +#+end_src
   2.230 +Later we will see how such assignment statements can in general be
   2.231 +modelled without using side effects.
   2.232 +
   2.233 +* Imperative Programming
   2.234 +Lambda calculus (and related languages, such as ``pure LISP'') is often
   2.235 +used for modelling the applicative constructs of programming languages.
   2.236 +However, they are generally thought of as inappropriate for modelling
   2.237 +imperative constructs. In this section we show how imperative constructs may
   2.238 +be modelled by applicative SCHEME constructs.
   2.239 +** Compound Statements
   2.240 +The simplest kind of imperative construct is the statement sequencer,
   2.241 +for example the compound statement in ALGOL:
   2.242 +#+begin_src algol
   2.243 +begin
   2.244 +S1;
   2.245 +S2;
   2.246 +end
   2.247 +#+end_src
   2.248 +
   2.249 +This construct has two interesting properties:
   2.250 +- (1) It performs statement S1 before S2, and so may be used for
   2.251 +  sequencing.
   2.252 +- (2) S1 is useful only for its side effects. (In ALGOL, S2 must also
   2.253 +  be a statement, and so is also useful only for side effects, but
   2.254 +  other languages have compound expressions containing a statement
   2.255 +  followed by an expression.)
   2.256 +
   2.257 +The ALGOL compound statement may actually contain any number of statements,
   2.258 +but such statements can be expressed as a series of nested two-statement
   2.259 +compounds. That is:
   2.260 +#+begin_src algol
   2.261 +begin
   2.262 +S1;
   2.263 +S2;
   2.264 +...
   2.265 +Sn-1;
   2.266 +Sn;
   2.267 +end
   2.268 +#+end_src
   2.269 +is equivalent to:
   2.270 +
   2.271 +#+begin_src algol
   2.272 +begin
   2.273 +S1;
   2.274 +begin
   2.275 +S2;
   2.276 +begin
   2.277 +...
   2.278 +
   2.279 +begin
   2.280 +Sn-1;
   2.281 +Sn;
   2.282 +end;
   2.283 +end;
   2.284 +end:
   2.285 +end
   2.286 +#+end_src
   2.287 +
   2.288 +It is not immediately apparent that this sequencing can be expressed in a
   2.289 +purely applicative language. We can, however, take advantage of the implicit
   2.290 +sequencing of applicative order evaluation. Thus, for example, we may write a
   2.291 +two-statement sequence as follows:
   2.292 +
   2.293 +#+begin_src clojure
   2.294 +((fn[dummy] S2) S1)
   2.295 +#+end_src
   2.296 +
   2.297 +where =dummy= is an identifier not used in S2. From this it is
   2.298 +manifest that the value of S1 is ignored, and so is useful only for
   2.299 +side effects. (Note that we did not claim that S1 is expressed in a
   2.300 +purely applicative language, but only that the sequencing can be so
   2.301 +expressed.) From now on we will use the form =(BLOCK S1 S2)= as an
   2.302 +abbreviation for this expression, and =(BLOCK S1 S2...Sn-1 Sn)= as an
   2.303 +abbreviation for 
   2.304 +
   2.305 +#+begin_src algol
   2.306 +(BLOCK S1 (BLOCK S2 (BLOCK ... (BLOCK Sn-1 Sn)...))) 
   2.307 +#+end_src
   2.308 +
   2.309 +** 2.2. The G0 TO Statement 
   2.310 +
   2.311 +A more general imperative structure is the compound statement with
   2.312 +labels and G0 T0s. Consider the following code fragment due to
   2.313 +Jacopini, taken from Knuth: [Knuth 74] 
   2.314 +#+begin_src algol
   2.315 +begin 
   2.316 +L1: if B1 then go to L2; S1;
   2.317 +    if B2 then go to L2; S2;
   2.318 +    go to L1;
   2.319 +L2: S3;
   2.320 +#+end_src
   2.321 +
   2.322 +It is perhaps surprising that this piece of code can be /syntactically/
   2.323 +transformed into a purely applicative style. For example, in SCHEME we
   2.324 +could write:
   2.325 +
   2.326 +#+begin_src clojure
   2.327 +(in-ns 'categorical.imperative)
   2.328 +(let
   2.329 +    [L1 (fn[]
   2.330 +	  (if B1 (L2) (do S1
   2.331 +			  (if B2 (L2) (do S2 (L1))))))
   2.332 +     L2 (fn[] S3)]
   2.333 +  (L1))
   2.334 +#+end_src
   2.335 +
   2.336 +As with the D0 loop, this transformation depends critically on SCHEME's
   2.337 +treatment of tail-recursion and on lexical scoping of variables. The labels
   2.338 +are names of functions of no arguments. In order to ‘go to" the labeled code,
   2.339 +we merely call the function named by that label.
   2.340 +
   2.341 +** 2.3. Simple Assignment
   2.342 +Of course, all this sequencing of statements is useless unless the
   2.343 +statements have side effects. An important side effect is assignment. For
   2.344 +example, one often uses assignment to place intermediate results in a named
   2.345 +location (i.e. a variable) so that they may be used more than once later
   2.346 +without recomputing them:
   2.347 +
   2.348 +#+begin_src algol
   2.349 +begin
   2.350 +real a2, sqrtdisc;
   2.351 +a2 := 2*a;
   2.352 +sqrtdisc := sqrt(b^2 - 4*a*c);
   2.353 +root1 := (- b + sqrtdisc) / a2;
   2.354 +root2 := (- b - sqrtdisc) / a2;
   2.355 +print(root1);
   2.356 +print(root2);
   2.357 +print(root1 + root2);
   2.358 +end
   2.359 +#+end_src
   2.360 +
   2.361 +It is well known that such naming of intermediate results may be accomplished
   2.362 +by calling a function and binding the formal parameter variables to the
   2.363 +results: 
   2.364 +
   2.365 +#+begin_src clojure
   2.366 +(fn [a2 sqrtdisc]
   2.367 +  ((fn[root1 root2]
   2.368 +    (do (println root1)
   2.369 +	(println root2)
   2.370 +	(println (+ root1 root2))))
   2.371 +  (/ (+ (- b) sqrtdisc) a2)
   2.372 +  (/ (- (- b) sqrtdisc) a2))
   2.373 +
   2.374 +  (* 2 a)
   2.375 +  (sqrt (- (* b b) (* 4 a c))))
   2.376 +#+end_src
   2.377 +This technique can be extended to handle all simple variable assignments which
   2.378 +appear as statements in blocks, even if arbitrary G0 T0 statements also appear
   2.379 +in such blocks. {Note Mccarthywins}
   2.380 +
   2.381 +For example, here is a program which uses G0 TO statements in the form
   2.382 +presented before; it determines the parity of a non-negative integer by
   2.383 +counting it down until it reaches zero.
   2.384 +
   2.385 +#+begin_src algol
   2.386 +begin
   2.387 +L1: if a = 0 then begin parity := 0; go to L2; end;
   2.388 +    a := a - 1;
   2.389 +    if a = 0 then begin parity := 1; go to L2; end;
   2.390 +    a := a - 1;
   2.391 +    go to L1;
   2.392 +L2: print(parity);
   2.393 +#+end_src
   2.394 +
   2.395 +This can be expressed in SCHEME:
   2.396 +
   2.397 +#+begin_src clojure
   2.398 +(let
   2.399 +    [L1 (fn [a parity]
   2.400 +	  (if (zero? a) (L2 a 0)
   2.401 +	      (L3 (dec a) parity)))
   2.402 +     L3 (fn [a parity]
   2.403 +	  (if (zero? a) (L2 a 1)
   2.404 +	      (L1 (dec a) parity)))
   2.405 +     L2 (fn [a parity]
   2.406 +	  (println parity))]
   2.407 +  (L1 a parity))
   2.408 +#+end_src
   2.409 +
   2.410 +The trick is to pass the set of variables which may be altered as arguments to
   2.411 +the label functions. {Note Flowgraph} It may be necessary to introduce new
   2.412 +labels (such as L3) so that an assignment may be transformed into the binding
   2.413 +for a function call. At worst, one may need as many labels as there are
   2.414 +statements (not counting the eliminated assignment and GO TO statements).
   2.415 +
   2.416 +** Compound Expressions '
   2.417 +At this point we are almost in a position to model the most general
   2.418 +form of compound statement. In LISP, this is called the 'PROG feature". In
   2.419 +addition to statement sequencing and G0 T0 statements, one can return a /value/
   2.420 +from a PROG by using the RETURN statement.
   2.421 +
   2.422 +Let us first consider the simplest compound statement, which in SCHEME
   2.423 +we call BLOCK. Recall that
   2.424 +=(BLOCK s1 sz)= is defined to be =((lambda (dummy) s2) s1)=
   2.425 +
   2.426 +Notice that this not only performs Sl before S2, but also returns the value of
   2.427 +S2. Furthermore, we defined =(BLOCK S1 S2 ... Sn)= so that it returns the value
   2.428 +of =Sn=. Thus BLOCK may be used as a compound expression, and models a LISP
   2.429 +PROGN, which is a PROG with no G0 T0 statements and an implicit RETURN of the
   2.430 +last ``statement'' (really an expression).
   2.431 +
   2.432 +Host LISP compilers compile D0 expressions by macro-expansion. We have
   2.433 +already seen one way to do this in SCHEME using only variable binding. A more
   2.434 +common technique is to expand the D0 into a PROG, using variable assignments
   2.435 +instead of bindings. Thus the iterative factorial program:
   2.436 +
   2.437 +#+begin_src clojure
   2.438 +(oarxnz FACT .
   2.439 +(LAMaoA (n) .
   2.440 +(D0 ((M N (- H 1))
   2.441 +(Ans 1 (* M Ans)))
   2.442 +((- H 0) A"$))))
   2.443 +#+end_src
   2.444 +
   2.445 +would expand into:
   2.446 +
   2.447 +#+begin_src clojure
   2.448 +(DEFINE FACT
   2.449 +. (LAMeoA (M)
   2.450 +(PRO6 (M Ans)
   2.451 +(sszro M n
   2.452 +Ans 1) ~
   2.453 +LP (tr (- M 0) (RETURN Ans))
   2.454 +(ssero M (- n 1)
   2.455 +Ans (' M Ans))
   2.456 +(60 LP))))
   2.457 +#+end_src
   2.458 +
   2.459 +where SSETQ is a simultaneous multiple assignment operator. (SSETQ is not a
   2.460 +SCHEME (or LISP) primitive. It can be defined in terms of a single assignment
   2.461 +operator, but we are more interested here in RETURN than in simultaneous
   2.462 +assignment. The SSETQ's will all be removed anyway and modelled by lambda
   2.463 +binding.) We can apply the same technique we used before to eliminate G0 T0
   2.464 +statements and assignments from compound statements:
   2.465 +
   2.466 +#+begin_src clojure
   2.467 +(DEFINE FACT
   2.468 +(LAHBOA (I)
   2.469 +(LABELS ((L1 (LAManA (M Ans)
   2.470 +(LP n 1)))
   2.471 +(LP (LAMaoA (M Ans)
   2.472 +(IF (- M o) (nztunn Ans)
   2.473 +(£2 H An$))))
   2.474 +(L2 (LAMaoA (M An )
   2.475 +(LP (- " 1) (' H flN$)))))
   2.476 +(L1 NIL NlL))))
   2.477 +#+end_src clojure
   2.478 +
   2.479 +We still haven't done anything about RETURN. Let's see...
   2.480 +- ==> the value of (FACT 0) is the value of (Ll NIL NIL)
   2.481 +- ==> which is the value of (LP 0 1)
   2.482 +- ==> which is the value of (IF (= 0 0) (RETURN 1) (L2 0 1))
   2.483 +- ==> which is the value of (RETURN 1) 
   2.484 +
   2.485 +Notice that if RETURN were the /identity
   2.486 +function/ (LAMBDA (X) X), we would get the right answer. This is in fact a
   2.487 +general truth: if we Just replace a call to RETURN with its argument, then
   2.488 +our old transformation on compound statements extends to general compound
   2.489 +expressions, i.e. PROG.
   2.490 +
   2.491 +* Continuations
   2.492 +Up to now we have thought of SCHEME's LAMBDA expressions as functions,
   2.493 +and of a combination such as =(G (F X Y))= as meaning ``apply the function F to
   2.494 +the values of X and Y, and return a value so that the function G can be
   2.495 +applied and return a value ...'' But notice that we have seldom used LAMBDA
   2.496 +expressions as functions. Rather, we have used them as control structures and
   2.497 +environment modifiers. For example, consider the expression:
   2.498 +=(BLOCK (PRINT 3) (PRINT 4))=
   2.499 +
   2.500 +This is defined to be an abbreviation for:
   2.501 +=((LAMBDA  (DUMMY) (PRINT 4)) (PRINT 3))=
   2.502 +
   2.503 +We do not care about the value of this BLOCK expression; it follows that we
   2.504 +do not care about the value of the =(LAMBDA (DUMMY) ...)=. We are not using
   2.505 +LAMBDA as a function at all.
   2.506 +
   2.507 +It is possible to write useful programs in terms of LAHBDA expressions
   2.508 +in which we never care about the value of /any/ lambda expression. We have
   2.509 +already demonstrated how one could represent any "FORTRAN" program in these
   2.510 +terms: all one needs is PROG (with G0 and SETQ), and PRINT to get the answers
   2.511 +out. The ultimate generalization of this imperative programing style is
   2.512 +/continuation-passing/. (Note Churchwins} .
   2.513 +
   2.514 +** Continuation-Passing Recursion
   2.515 +Consider the following alternative definition of FACT. It has an extra
   2.516 +argument, the continuation, which is a function to call with the answer, when
   2.517 +we have it, rather than return a value
   2.518 +
   2.519 +#+begin_src algol.
   2.520 +procedure Inc!(n, c); value n, c;
   2.521 +integer n: procedure c(integer value);
   2.522 +if n-=0 then c(l) else
   2.523 +begin
   2.524 +procedure l(!mp(d) value a: integer a;
   2.525 +c(mm);
   2.526 +Iacl(n-1, romp):
   2.527 +end;
   2.528 +#+end_src
   2.529 +
   2.530 +#+begin_src clojure
   2.531 +(in-ns 'categorical.imperative)
   2.532 +(defn fact-cps[n k]
   2.533 +  (if (zero? n) (k 1)
   2.534 +      (recur (dec n) (fn[a] (k (* n a))))))
   2.535 +#+end_src clojure
   2.536 +It is fairly clumsy to use this version of‘ FACT in ALGOL; it is necessary to
   2.537 +do something like this:
   2.538 +
   2.539 +#+begin_src algol
   2.540 +begin
   2.541 +integer ann
   2.542 +procedure :emp(x); value 2:; integer x;
   2.543 +ans :1 x;
   2.544 +]'act(3. temp);
   2.545 +comment Now the variable "am" has 6;
   2.546 +end;
   2.547 +#+end_src
   2.548 +
   2.549 +Procedure =fact= does not return a value, nor does =temp=; we must use a side
   2.550 +effect to get the answer out.
   2.551 +
   2.552 +=FACT= is somewhat easier to use in SCHEME. We can call it like an
   2.553 +ordinary function in SCHEME if we supply an identity function as the second
   2.554 +argument. For example, =(FACT 3 (LAMBDA (X) X))= returns 6. Alternatively, we
   2.555 +could write =(FACT 3 (LAHBDA (X) (PRINT X)))=; we do not care about the value
   2.556 +of this, but about what gets printed. A third way to use the value is to
   2.557 +write
   2.558 +=(FACT 3 (LAMBDA (x) (SQRT x)))=
   2.559 +instead of
   2.560 +=(SQRT (FACT 3 (LAMBDA (x) x)))=
   2.561 +
   2.562 +In either of these cases we care about the value of the continuation given to
   2.563 +FACT. Thus we care about the value of FACT if and only if we care about the
   2.564 +value of its continuation!
   2.565 +
   2.566 +We can redefine other functions to take continuations in the same way.
   2.567 +For example, suppose we had arithmetic primitives which took continuations; to
   2.568 +prevent confusion, call the version of "+" which takes a continuation '++",
   2.569 +etc. Instead of writing
   2.570 +=(- (+ B Z)(* 4 A C))=
   2.571 +we can write
   2.572 +#+begin_src clojure
   2.573 +(in-ns 'categorical.imperative)
   2.574 +(defn enable-continuation "Makes f take a continuation as an additional argument."[f]
   2.575 +  (fn[& args] ((fn[k] (k (apply f (reverse (rest (reverse args)))))) (last args)) ))
   2.576 +(def +& (enable-continuation +))
   2.577 +(def *& (enable-continuation *))
   2.578 +(def -& (enable-continuation -))
   2.579 +
   2.580 +
   2.581 +(defn quadratic[a b c k]
   2.582 +(*& b b
   2.583 +    (fn[x] (*& 4 a c
   2.584 +	       (fn[y]
   2.585 +		 (-& x y k))))))
   2.586 +#+end_src
   2.587 +
   2.588 +where =k= is the continuation for the entire expression.
   2.589 +
   2.590 +This is an obscure way to write an algebraic expression, and we would
   2.591 +not advise writing code this way in general, but continuation-passing brings
   2.592 +out certain important features of the computation:
   2.593 + - [1] The operations to be performed appear in the order in which they are
   2.594 +performed. In fact, they /must/ be performed in this
   2.595 +order. Continuation- passing removes the need for the rule about
   2.596 +left-to-right argument evaluation{Note Evalorder)
   2.597 +- [2] In the usual applicative expression there are two implicit
   2.598 +  temporary values: those of =(* B B)= and =(* 4 A C)=. The first of
   2.599 +  these values must be preserved over the computation of the second,
   2.600 +  whereas the second is used as soon as it is produced. These facts
   2.601 +  are /manifest/ in the appearance and use of the variable X and Y in
   2.602 +  the continuation-passing version.  
   2.603 +
   2.604 +In short, the continuation-passing version specifies /exactly/ and
   2.605 +  explicitly what steps are necessary to compute the value of the
   2.606 +  expression.  One can think of conventional functional application
   2.607 +  for value as being an abbreviation for the more explicit
   2.608 +  continuation-passing style. Alternatively, one can think of the
   2.609 +  interpreter as supplying to each function an implicit default
   2.610 +  continuation of one argument. This continuation will receive the
   2.611 +  value of the function as its argument, and then carry on the
   2.612 +  computation. In an interpreter this implicit continuation is
   2.613 +  represented by the control stack mechanism for function returns.
   2.614 +  Now consider what computational steps are implied by: 
   2.615 +
   2.616 +=(LAMBDA (A B C ...) (F X Y Z ...))= when we "apply" the LAMBDA
   2.617 +  expression we have some values to apply it to; we let the names A,
   2.618 +  B, C ... refer to these values. We then determine the values of X,
   2.619 +  Y, Z ... and pass these values (along with "the buck",
   2.620 +  i.e. control!) to the lambda expression F (F is either a lambda
   2.621 +  expression or a name for one).  Passing control to F is an
   2.622 +  unconditional transfer. (Note Jrsthack) {Note Hewitthack) Note that
   2.623 +  we want values from X, Y, Z, ... If these are simple expressions,
   2.624 +  such as variables, constants, or LAMBDA expressions, the evaluation
   2.625 +  process is trivial, in that no temporary storage is required. In
   2.626 +  pure continuation-passing style, all evaluations are trivial: no
   2.627 +  combination is nested within another, and therefore no ‘hidden
   2.628 +  temporaries" are required.  But if X is a combination, say (G P Q),
   2.629 +  then we want to think of G as a function, because we want a value
   2.630 +  from it, and we will need an implicit temporary place to keep the
   2.631 +  result while evaluating Y and Z. (An interpreter usually keeps these
   2.632 +  temporary places in the control stack!) On the other hand, we do not
   2.633 +  necessarily need a value from F. This is what we mean by tail-
   2.634 +  recursion: F is called tail-recursively, whereas G is not. A better
   2.635 +  name for tail-recursion would be "tail-transfer", since no real
   2.636 +  recursion is implied.  This is why we have made such a fuss about
   2.637 +  tail-recursion: it can be used for transfer of control without
   2.638 +  making any commitment about whether the expression expected to
   2.639 +  return a value. Thus it can be used to model statement-like control
   2.640 +  structures. Put another way, tail—recursion does not require a
   2.641 +  control stack as nested recursion does. In our models of iteration
   2.642 +  and imperative style all the LAMBDA expressions used for control (to
   2.643 +  simulate GO statements, for example) are called in tail-recursive
   2.644 +  fashion.
   2.645 +
   2.646 +** Escape Expressions
   2.647 +Reynolds [Reynolds 72] defines the construction
   2.648 += escape x in r =
   2.649 +
   2.650 +to evaluate the expression $r$ in an environment such that the variable $x$ is
   2.651 +bound to an escape function. If the escape function is never applied, then
   2.652 +the value of the escape expression is the value of $r$. If the escape function
   2.653 +is applied to an argument $a$, however, then evaluation of $r$ is aborted and the
   2.654 +escape expression returns $a$. {Note J-operator} (Reynolds points out that
   2.655 +this definition is not quite accurate, since the escape function may be called
   2.656 +even after the escape expression has returned a value; if this happens, it
   2.657 +“returns again"!)
   2.658 +
   2.659 +As an example of the use of an escape expression, consider this
   2.660 +procedure to compute the harmonic mean of an array of numbers. If any of the
   2.661 +numbers is zero, we want the answer to be zero. We have a function hannaunl
   2.662 +which will sum the reciprocals of numbers in an array, or call an escape
   2.663 +function with zero if any of the numbers is zero. (The implementation shown
   2.664 +here is awkward because ALGOL requires that a function return its value by
   2.665 +assignment.)
   2.666 +#+begin_src algol
   2.667 +begin
   2.668 +real procedure Imrmsum(a, n. escfun)§ p
   2.669 +real array at integer n; real procedure esciun(real);
   2.670 +begin
   2.671 +real sum;
   2.672 +sum := 0;
   2.673 +for i :1 0 until n-l do
   2.674 +begin
   2.675 +if a[i]=0 then cscfun(0);
   2.676 +sum :1 sum ¢ I/a[i];
   2.677 +enm
   2.678 +harmsum SI sum;
   2.679 +end: .
   2.680 +real array b[0:99]:
   2.681 +print(escape x in I00/hm-m.mm(b, 100, x));
   2.682 +end
   2.683 +#+end_src
   2.684 +
   2.685 +If harmsum exits normally, the number of elements is divided by the sum and
   2.686 +printed. Otherwise, zero is returned from the escape expression and printed
   2.687 +without the division ever occurring.
   2.688 +This program can be written in SCHEME using the built-in escape
   2.689 +operator =CATCH=:
   2.690 +
   2.691 +#+begin_src clojure
   2.692 +(in-ns 'categorical.imperative)
   2.693 +(defn harmonic-sum[coll escape]
   2.694 +  ((fn [i sum]
   2.695 +     (cond (= i (count coll) ) sum
   2.696 +	   (zero? (nth coll i)) (escape 0)
   2.697 +	   :else (recur (inc i) (+ sum (/ 1 (nth coll i))))))
   2.698 +   0 0))
   2.699 +
   2.700 +#+end_src
   2.701 +
   2.702 +This actually works, but elucidates very little about the nature of ESCAPE.
   2.703 +We can eliminate the use of CATCH by using continuation-passing. Let us do
   2.704 +for HARMSUM what we did earlier for FACT. Let it take an extra argument C,
   2.705 +which is called as a function on the result.
   2.706 +
   2.707 +#+begin_src clojure
   2.708 +(in-ns 'categorical.imperative)
   2.709 +(defn harmonic-sum-escape[coll escape k]
   2.710 +  ((fn[i sum]
   2.711 +    (cond (= i (count coll)) (k sum)
   2.712 +	  (zero? (nth coll i)) (escape 0)
   2.713 +	  (recur (inc i) (+ sum (/ 1 (nth coll i))))))
   2.714 +   0 0))
   2.715 +
   2.716 +(let [B (range 0 100)
   2.717 +      after-the-catch println]
   2.718 +  (harmonic-sum-escape B after-the-catch (fn[y] (after-the-catch (/ 100 y)))))
   2.719 +
   2.720 +#+end_src
   2.721 +
   2.722 +Notice that if we use ESCFUN, then C does not get called. In this way the
   2.723 +division is avoided. This example shows how ESCFUN may be considered to be an
   2.724 +"alternate continuation".
   2.725 +
   2.726 +** Dynamic Variable Scoping
   2.727 +In this section we will consider the problem of dynamically scoped, or
   2.728 +"fluid", variables. These do not exist in ALGOL, but are typical of many LISP
   2.729 +implementations, ECL, and APL. He will see that fluid variables may be
   2.730 +modelled in more than one way, and that one of these is closely related to
   2.731 +continuation—pass1ng.
   2.732 +
   2.733 +*** Free (Global) Variables
   2.734 +Consider the following program to compute square roots:
   2.735 +
   2.736 +#+begin_src clojure
   2.737 +(defn sqrt[x tolerance]
   2.738 +  (
   2.739 +(DEFINE soar
   2.740 +(LAHBDA (x EPSILON)
   2.741 +(Pace (ANS)
   2.742 +(stro ANS 1.0)
   2.743 +A (coup ((< (ADS (-s x (~s ANS ANS))) EPSILON)
   2.744 +(nzruau ANS))) '
   2.745 +(sero ANS (//s (+5 x (//s x ANS)) 2.0))
   2.746 +(60 A)))) .
   2.747 +This function takes two arguments: the radicand and the numerical tolerance
   2.748 +for the approximation. Now suppose we want to write a program QUAD to compute
   2.749 +solutions to a quadratic equation; p
   2.750 +(perms QUAD
   2.751 +(LAHDDA (A a c)
   2.752 +((LAHBDA (A2 sonmsc) '
   2.753 +(LIST (/ (+ (- a) SQRTDISC) AZ)
   2.754 +(/ (- (- B) SORTOISC) AZ)))
   2.755 +(' 2 A)
   2.756 +- (SORT (- (9 D 2) (' 4 A C)) (tolerance>))))
   2.757 +#+end_src
   2.758 +It is not clear what to write for (tolerance). One alternative is to pick
   2.759 +some tolerance for use by QUAD and write it as a constant in the code. This
   2.760 +is undesirable because it makes QUAD inflexible and hard to change. _Another
   2.761 +is to make QUAD take an extra argument and pass it to SQRT:
   2.762 +(DEFINE QUAD
   2.763 +(LANODA (A 8 C EPSILON)
   2.764 +(soar ... EPSILON) ...))
   2.765 +This is undesirable because EPSILDN is not really part of the problem QUAD is
   2.766 +supposed to solve, and we don't want the user to have to provide it.
   2.767 +Furthermore, if QUAD were built into some larger function, and that into
   2.768 +another, all these functions would have to pass EPSILON down as an extra
   2.769 +argument. A third.possibi1ity would be to pass the SQRT function as an
   2.770 +argument to QUAD (don't laugh!), the theory being to bind EPSILON at the
   2.771 +appropriate level like this: A U‘ A
   2.772 +(QUAD 3 A 5 (LAMBDA (X) (SORT X <toIerance>)))
   2.773 +where we define QUAD as:
   2.774 +(DEFINE QUAD
   2.775 +(LAMBDA (A a c soar) ...))
     3.1 Binary file categorical/ltxpng/plausible_0dd51e4ab8cb4eb616439d758fbec4ed120e8a15.png has changed
     4.1 Binary file categorical/ltxpng/plausible_327b1246bf52889b71445e990ea38a8414f683cc.png has changed
     5.1 Binary file categorical/ltxpng/plausible_34a4f0f7fd91bf7212f437fd9e0fae7c04dbdae1.png has changed
     6.1 Binary file categorical/ltxpng/plausible_5072ddd55abeb45994e1f467e2041032d8a90350.png has changed
     7.1 Binary file categorical/ltxpng/plausible_5434f18d3d7ac2858cd4f914be8f5d2b49c79a90.png has changed
     8.1 Binary file categorical/ltxpng/plausible_60c89d70f35bbeef7c8c5572941c3398e65f9eb1.png has changed
     9.1 Binary file categorical/ltxpng/plausible_671e7f9a1d6c0ed854ad469bb2e6446cf536f6ce.png has changed
    10.1 Binary file categorical/ltxpng/plausible_70e445784826d50e75fa759496de7dbd78e0c29e.png has changed
    11.1 Binary file categorical/ltxpng/plausible_9471153ffb8045fd30a14628197f6e1a31c4d2bf.png has changed
    12.1 Binary file categorical/ltxpng/plausible_c0cfa0be1f5f4c93c4a07d2bf03f296a87ddb3f5.png has changed
    13.1 Binary file categorical/ltxpng/plausible_d282b164f31f8cb4d3238ea37d09715da89272aa.png has changed
    14.1 Binary file categorical/ltxpng/plausible_dd81a36f0fc30866fc59a06fba09770696fbcfce.png has changed
    15.1 Binary file categorical/ltxpng/plausible_df22ff07c07c3eae08269551b79e75e13ed321f9.png has changed
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/categorical/monad.clj	Fri Oct 28 00:03:05 2011 -0700
    16.3 @@ -0,0 +1,14 @@
    16.4 +
    16.5 +(ns categorical.monad)
    16.6 +(use 'clojure.contrib.monads)
    16.7 +
    16.8 +(in-ns 'categorical.monad)
    16.9 +
   16.10 +;; To implement nondeterministic programs, we'll use a lazy seq to represent a value which may be any one of the members of seq.
   16.11 +
   16.12 +(defmonad amb
   16.13 +  [
   16.14 +   m-result (fn[& vals] (cons 'amb vals))
   16.15 +   m-bind (fn[amb-seq f] (cons 'amb (map f (rest amb-seq))))
   16.16 +   ]
   16.17 +)
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/categorical/monad.html	Fri Oct 28 00:03:05 2011 -0700
    17.3 @@ -0,0 +1,251 @@
    17.4 +<?xml version="1.0" encoding="iso-8859-1"?>
    17.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    17.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    17.7 +<html xmlns="http://www.w3.org/1999/xhtml"
    17.8 +lang="en" xml:lang="en">
    17.9 +<head>
   17.10 +<title>Monads in CS and Math</title>
   17.11 +<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
   17.12 +<meta name="generator" content="Org-mode"/>
   17.13 +<meta name="generated" content="2011-07-11 03:07:07 EDT"/>
   17.14 +<meta name="author" content="Robert McIntyre"/>
   17.15 +<meta name="description" content=""/>
   17.16 +<meta name="keywords" content=""/>
   17.17 +<style type="text/css">
   17.18 + <!--/*--><![CDATA[/*><!--*/
   17.19 +  html { font-family: Times, serif; font-size: 12pt; }
   17.20 +  .title  { text-align: center; }
   17.21 +  .todo   { color: red; }
   17.22 +  .done   { color: green; }
   17.23 +  .tag    { background-color: #add8e6; font-weight:normal }
   17.24 +  .target { }
   17.25 +  .timestamp { color: #bebebe; }
   17.26 +  .timestamp-kwd { color: #5f9ea0; }
   17.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
   17.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
   17.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
   17.30 +  p.verse { margin-left: 3% }
   17.31 +  pre {
   17.32 +	border: 1pt solid #AEBDCC;
   17.33 +	background-color: #F3F5F7;
   17.34 +	padding: 5pt;
   17.35 +	font-family: courier, monospace;
   17.36 +        font-size: 90%;
   17.37 +        overflow:auto;
   17.38 +  }
   17.39 +  table { border-collapse: collapse; }
   17.40 +  td, th { vertical-align: top;  }
   17.41 +  th.right  { text-align:center;  }
   17.42 +  th.left   { text-align:center;   }
   17.43 +  th.center { text-align:center; }
   17.44 +  td.right  { text-align:right;  }
   17.45 +  td.left   { text-align:left;   }
   17.46 +  td.center { text-align:center; }
   17.47 +  dt { font-weight: bold; }
   17.48 +  div.figure { padding: 0.5em; }
   17.49 +  div.figure p { text-align: center; }
   17.50 +  textarea { overflow-x: auto; }
   17.51 +  .linenr { font-size:smaller }
   17.52 +  .code-highlighted {background-color:#ffff00;}
   17.53 +  .org-info-js_info-navigation { border-style:none; }
   17.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
   17.55 +                               white-space:nowrap; }
   17.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
   17.57 +                                 font-weight:bold; }
   17.58 +  /*]]>*/-->
   17.59 +</style>
   17.60 +<script type="text/javascript">
   17.61 +<!--/*--><![CDATA[/*><!--*/
   17.62 + function CodeHighlightOn(elem, id)
   17.63 + {
   17.64 +   var target = document.getElementById(id);
   17.65 +   if(null != target) {
   17.66 +     elem.cacheClassElem = elem.className;
   17.67 +     elem.cacheClassTarget = target.className;
   17.68 +     target.className = "code-highlighted";
   17.69 +     elem.className   = "code-highlighted";
   17.70 +   }
   17.71 + }
   17.72 + function CodeHighlightOff(elem, id)
   17.73 + {
   17.74 +   var target = document.getElementById(id);
   17.75 +   if(elem.cacheClassElem)
   17.76 +     elem.className = elem.cacheClassElem;
   17.77 +   if(elem.cacheClassTarget)
   17.78 +     target.className = elem.cacheClassTarget;
   17.79 + }
   17.80 +/*]]>*///-->
   17.81 +</script>
   17.82 +<script type="text/javascript" src="http://orgmode.org/mathjax/MathJax.js">
   17.83 +<!--/*--><![CDATA[/*><!--*/
   17.84 +    MathJax.Hub.Config({
   17.85 +        // Only one of the two following lines, depending on user settings
   17.86 +        // First allows browser-native MathML display, second forces HTML/CSS
   17.87 +        //  config: ["MMLorHTML.js"], jax: ["input/TeX"],
   17.88 +            jax: ["input/TeX", "output/HTML-CSS"],
   17.89 +        extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js",
   17.90 +                     "TeX/noUndefined.js"],
   17.91 +        tex2jax: {
   17.92 +            inlineMath: [ ["\\(","\\)"] ],
   17.93 +            displayMath: [ ['$$','$$'], ["\\[","\\]"], ["\\begin{displaymath}","\\end{displaymath}"] ],
   17.94 +            skipTags: ["script","noscript","style","textarea","pre","code"],
   17.95 +            ignoreClass: "tex2jax_ignore",
   17.96 +            processEscapes: false,
   17.97 +            processEnvironments: true,
   17.98 +            preview: "TeX"
   17.99 +        },
  17.100 +        showProcessingMessages: true,
  17.101 +        displayAlign: "center",
  17.102 +        displayIndent: "2em",
  17.103 +
  17.104 +        "HTML-CSS": {
  17.105 +             scale: 100,
  17.106 +             availableFonts: ["STIX","TeX"],
  17.107 +             preferredFont: "TeX",
  17.108 +             webFont: "TeX",
  17.109 +             imageFont: "TeX",
  17.110 +             showMathMenu: true,
  17.111 +        },
  17.112 +        MMLorHTML: {
  17.113 +             prefer: {
  17.114 +                 MSIE:    "MML",
  17.115 +                 Firefox: "MML",
  17.116 +                 Opera:   "HTML",
  17.117 +                 other:   "HTML"
  17.118 +             }
  17.119 +        }
  17.120 +    });
  17.121 +/*]]>*///-->
  17.122 +</script>
  17.123 +</head>
  17.124 +<body>
  17.125 +<div id="content">
  17.126 +
  17.127 +
  17.128 +
  17.129 +<h1>
  17.130 +Monads in CS and Math
  17.131 +</h1>
  17.132 +
  17.133 +<p>
  17.134 +The purpose of a <i>monad</i> is to introduce a new data type into your
  17.135 +language and to integrate it with existing types; a monad augments a
  17.136 +pre-existing data type \(A\), creating a new type \(B\). 
  17.137 +</p>
  17.138 +<p>
  17.139 +When describing monads, I will use the following terminology:
  17.140 +</p><ul>
  17.141 +<li>Values of type \(A\) are called <b>ordinary values</b>, because they belong
  17.142 +  to the pre-existing data type.
  17.143 +</li>
  17.144 +<li>Values of type \(B\) are called <b>monadic values</b>, because they
  17.145 +  belong to the type introduced by the monad.
  17.146 +</li>
  17.147 +<li>A function \(A\rightarrow B\) is called a <b>monadic function</b>; such
  17.148 +  functions accept regular values as input and return monadic values.
  17.149 +</li>
  17.150 +</ul>
  17.151 +
  17.152 +
  17.153 +<p>
  17.154 +A monad consists of
  17.155 +two components for achieving this purpose: 
  17.156 +</p>
  17.157 +<dl>
  17.158 +<dt>A function that converts ordinary values into monadic values</dt><dd>
  17.159 +<p>
  17.160 +     First, in order to create a new data type, each monad has an
  17.161 +  <i>upgrade function</i> which systematically adds structure to values of
  17.162 +  the existing data type, \(A\). Because the upgrade function produces
  17.163 +  enhanced values in a systematic way, the enhanced values constitute
  17.164 +  a sort of new data type, \(B\).
  17.165 +</p></dd>
  17.166 +</dl>
  17.167 +
  17.168 +
  17.169 +<blockquote>
  17.170 +
  17.171 +
  17.172 +\(\text{upgrade}:A\rightarrow B\)
  17.173 +
  17.174 +</blockquote>
  17.175 +
  17.176 +
  17.177 +<dl>
  17.178 +<dt>A function that enables monadic functions to accept monadic values</dt><dd>Second, each monad has a <i>pipe function</i> which is a
  17.179 +  protocol for combining a monadic function and a monadic value to
  17.180 +  produce a monadic value. The pipe function facilitates composition:
  17.181 +  notice that a collection of monadic functions \(A\rightarrow B\) is composable only if they have been modified by the
  17.182 +  pipe function to become functions of type \(B\rightarrow B\), otherwise their input and output types do not match.
  17.183 +</dd>
  17.184 +</dl>
  17.185 +
  17.186 +<blockquote>
  17.187 +
  17.188 +
  17.189 +\(\text{pipe}:B\times B^A\rightarrow B\)
  17.190 +
  17.191 +</blockquote>
  17.192 +
  17.193 +
  17.194 +
  17.195 +
  17.196 +
  17.197 +
  17.198 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">ns</span> categorical.monad)
  17.199 +
  17.200 +</pre>
  17.201 +
  17.202 +
  17.203 +
  17.204 +
  17.205 +
  17.206 +<div id="table-of-contents">
  17.207 +<h2>Table of Contents</h2>
  17.208 +<div id="text-table-of-contents">
  17.209 +<ul>
  17.210 +<li><a href="#sec-1">1 Examples of monads </a>
  17.211 +<ul>
  17.212 +<li><a href="#sec-1-1">1.1 The nondeterministic  monad </a></li>
  17.213 +</ul>
  17.214 +</li>
  17.215 +</ul>
  17.216 +</div>
  17.217 +</div>
  17.218 +
  17.219 +<div id="outline-container-1" class="outline-2">
  17.220 +<h2 id="sec-1"><span class="section-number-2">1</span> Examples of monads </h2>
  17.221 +<div class="outline-text-2" id="text-1">
  17.222 +
  17.223 +
  17.224 +</div>
  17.225 +
  17.226 +<div id="outline-container-1-1" class="outline-3">
  17.227 +<h3 id="sec-1-1"><span class="section-number-3">1.1</span> The nondeterministic  monad </h3>
  17.228 +<div class="outline-text-3" id="text-1-1">
  17.229 +
  17.230 +
  17.231 +<p>
  17.232 +We'll implement nondeterministic programming by defining a monad <code>amb</code>
  17.233 +that transforms ordinary deterministic functions into functions that ``ambiguously'' return zero or more
  17.234 +values. 
  17.235 +</p>
  17.236 +
  17.237 +
  17.238 +
  17.239 +<pre class="src src-clojure"></pre>
  17.240 +
  17.241 +
  17.242 +
  17.243 +</div>
  17.244 +</div>
  17.245 +</div>
  17.246 +<div id="postamble">
  17.247 +<p class="date">Date: 2011-07-11 03:07:07 EDT</p>
  17.248 +<p class="author">Author: Robert McIntyre</p>
  17.249 +<p class="creator">Org version 7.6 with Emacs version 23</p>
  17.250 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  17.251 +</div>
  17.252 +</div>
  17.253 +</body>
  17.254 +</html>
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/categorical/monad.org	Fri Oct 28 00:03:05 2011 -0700
    18.3 @@ -0,0 +1,76 @@
    18.4 +#+TITLE: Monads in CS and Math
    18.5 +#+BEGIN_HTML
    18.6 +<h1>
    18.7 +{{{TITLE}}}
    18.8 +</h1>
    18.9 +#+END_HTML
   18.10 +
   18.11 +The purpose of a /monad/ is to introduce a new data type into your
   18.12 +language and to integrate it with existing types; a monad augments a
   18.13 +pre-existing data type $A$, creating a new type $B$. 
   18.14 +
   18.15 +When describing monads, I will use the following terminology:
   18.16 +- Values of type $A$ are called *ordinary values*, because they belong
   18.17 +  to the pre-existing data type.
   18.18 +- Values of type $B$ are called *monadic values*, because they
   18.19 +  belong to the type introduced by the monad.
   18.20 +- A function $A\rightarrow B$ is called a *monadic function*; such
   18.21 +  functions accept regular values as input and return monadic values.
   18.22 +
   18.23 +
   18.24 +
   18.25 +A monad consists of
   18.26 +two components for achieving this purpose: 
   18.27 +
   18.28 +- A function that converts ordinary values into monadic values ::
   18.29 +     First, in order to create a new data type, each monad has an
   18.30 +  /upgrade function/ which systematically adds structure to values of
   18.31 +  the existing data type, $A$. Because the upgrade function produces
   18.32 +  enhanced values in a systematic way, the enhanced values constitute
   18.33 +  a sort of new data type, $B$.
   18.34 +
   18.35 +#+begin_quote
   18.36 +$\text{upgrade}:A\rightarrow B$
   18.37 +#+end_quote
   18.38 +
   18.39 +- A function that enables monadic functions to accept monadic values :: Second, each monad has a /pipe function/ which is a
   18.40 +  protocol for combining a monadic function and a monadic value to
   18.41 +  produce a monadic value. The pipe function facilitates composition:
   18.42 +  notice that a collection of monadic functions $A\rightarrow B$ is composable only if they have been modified by the
   18.43 +  pipe function to become functions of type $B\rightarrow B$, otherwise their input and output types do not match.
   18.44 +#+begin_quote
   18.45 +$\text{pipe}:B\times B^A\rightarrow B$
   18.46 +#+end_quote
   18.47 +
   18.48 +#+srcname: intro
   18.49 +#+begin_src clojure :results silent
   18.50 +(ns categorical.monad)
   18.51 +(use 'clojure.contrib.monads)
   18.52 +#+end_src
   18.53 +
   18.54 +
   18.55 +* Examples of monads
   18.56 +** The nondeterministic  monad
   18.57 +
   18.58 +We'll implement nondeterministic programming by defining a monad =amb=
   18.59 +that transforms ordinary deterministic functions into functions that ``ambiguously'' return zero or more
   18.60 +values. 
   18.61 +
   18.62 +#+srcname: stuff
   18.63 +#+begin_src clojure :results silent
   18.64 +(in-ns 'categorical.monad)
   18.65 +
   18.66 +;; To implement nondeterministic programs, we'll use a lazy seq to represent a value which may be any one of the members of seq.
   18.67 +
   18.68 +(defmonad amb
   18.69 +  [
   18.70 +   m-result (fn[& vals] (cons 'amb vals))
   18.71 +   m-bind (fn[amb-seq f] (cons 'amb (map f (rest amb-seq))))
   18.72 +   ]
   18.73 +)
   18.74 +#+end_src
   18.75 +
   18.76 +#+begin_src clojure :results silent :tangle monad.clj :noweb yes
   18.77 +<<intro>>
   18.78 +<<stuff>>
   18.79 +#+end_src
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/categorical/morphisms.html	Fri Oct 28 00:03:05 2011 -0700
    19.3 @@ -0,0 +1,240 @@
    19.4 +<?xml version="1.0" encoding="iso-8859-1"?>
    19.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    19.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    19.7 +<html xmlns="http://www.w3.org/1999/xhtml"
    19.8 +lang="en" xml:lang="en">
    19.9 +<head>
   19.10 +<title>Categorical Programs</title>
   19.11 +<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
   19.12 +<meta name="generator" content="Org-mode"/>
   19.13 +<meta name="generated" content="2011-07-01 12:28:39 CDT"/>
   19.14 +<meta name="author" content="Dylan Holmes"/>
   19.15 +<meta name="description" content=""/>
   19.16 +<meta name="keywords" content=""/>
   19.17 +<style type="text/css">
   19.18 + <!--/*--><![CDATA[/*><!--*/
   19.19 +  html { font-family: Times, serif; font-size: 12pt; }
   19.20 +  .title  { text-align: center; }
   19.21 +  .todo   { color: red; }
   19.22 +  .done   { color: green; }
   19.23 +  .tag    { background-color: #add8e6; font-weight:normal }
   19.24 +  .target { }
   19.25 +  .timestamp { color: #bebebe; }
   19.26 +  .timestamp-kwd { color: #5f9ea0; }
   19.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
   19.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
   19.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
   19.30 +  p.verse { margin-left: 3% }
   19.31 +  pre {
   19.32 +	border: 1pt solid #AEBDCC;
   19.33 +	background-color: #F3F5F7;
   19.34 +	padding: 5pt;
   19.35 +	font-family: courier, monospace;
   19.36 +        font-size: 90%;
   19.37 +        overflow:auto;
   19.38 +  }
   19.39 +  table { border-collapse: collapse; }
   19.40 +  td, th { vertical-align: top;  }
   19.41 +  th.right  { text-align:center;  }
   19.42 +  th.left   { text-align:center;   }
   19.43 +  th.center { text-align:center; }
   19.44 +  td.right  { text-align:right;  }
   19.45 +  td.left   { text-align:left;   }
   19.46 +  td.center { text-align:center; }
   19.47 +  dt { font-weight: bold; }
   19.48 +  div.figure { padding: 0.5em; }
   19.49 +  div.figure p { text-align: center; }
   19.50 +  textarea { overflow-x: auto; }
   19.51 +  .linenr { font-size:smaller }
   19.52 +  .code-highlighted {background-color:#ffff00;}
   19.53 +  .org-info-js_info-navigation { border-style:none; }
   19.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
   19.55 +                               white-space:nowrap; }
   19.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
   19.57 +                                 font-weight:bold; }
   19.58 +  /*]]>*/-->
   19.59 +</style>
   19.60 +<link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
   19.61 +<script type="text/javascript">
   19.62 +<!--/*--><![CDATA[/*><!--*/
   19.63 + function CodeHighlightOn(elem, id)
   19.64 + {
   19.65 +   var target = document.getElementById(id);
   19.66 +   if(null != target) {
   19.67 +     elem.cacheClassElem = elem.className;
   19.68 +     elem.cacheClassTarget = target.className;
   19.69 +     target.className = "code-highlighted";
   19.70 +     elem.className   = "code-highlighted";
   19.71 +   }
   19.72 + }
   19.73 + function CodeHighlightOff(elem, id)
   19.74 + {
   19.75 +   var target = document.getElementById(id);
   19.76 +   if(elem.cacheClassElem)
   19.77 +     elem.className = elem.cacheClassElem;
   19.78 +   if(elem.cacheClassTarget)
   19.79 +     target.className = elem.cacheClassTarget;
   19.80 + }
   19.81 +/*]]>*///-->
   19.82 +</script>
   19.83 +<script type="text/javascript" src="http://orgmode.org/mathjax/MathJax.js">
   19.84 +<!--/*--><![CDATA[/*><!--*/
   19.85 +    MathJax.Hub.Config({
   19.86 +        // Only one of the two following lines, depending on user settings
   19.87 +        // First allows browser-native MathML display, second forces HTML/CSS
   19.88 +        //  config: ["MMLorHTML.js"], jax: ["input/TeX"],
   19.89 +            jax: ["input/TeX", "output/HTML-CSS"],
   19.90 +        extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js",
   19.91 +                     "TeX/noUndefined.js"],
   19.92 +        tex2jax: {
   19.93 +            inlineMath: [ ["\\(","\\)"] ],
   19.94 +            displayMath: [ ['$$','$$'], ["\\[","\\]"], ["\\begin{displaymath}","\\end{displaymath}"] ],
   19.95 +            skipTags: ["script","noscript","style","textarea","pre","code"],
   19.96 +            ignoreClass: "tex2jax_ignore",
   19.97 +            processEscapes: false,
   19.98 +            processEnvironments: true,
   19.99 +            preview: "TeX"
  19.100 +        },
  19.101 +        showProcessingMessages: true,
  19.102 +        displayAlign: "center",
  19.103 +        displayIndent: "2em",
  19.104 +
  19.105 +        "HTML-CSS": {
  19.106 +             scale: 100,
  19.107 +             availableFonts: ["STIX","TeX"],
  19.108 +             preferredFont: "TeX",
  19.109 +             webFont: "TeX",
  19.110 +             imageFont: "TeX",
  19.111 +             showMathMenu: true,
  19.112 +        },
  19.113 +        MMLorHTML: {
  19.114 +             prefer: {
  19.115 +                 MSIE:    "MML",
  19.116 +                 Firefox: "MML",
  19.117 +                 Opera:   "HTML",
  19.118 +                 other:   "HTML"
  19.119 +             }
  19.120 +        }
  19.121 +    });
  19.122 +/*]]>*///-->
  19.123 +</script>
  19.124 +</head>
  19.125 +<body>
  19.126 +<div id="content">
  19.127 +
  19.128 +
  19.129 +
  19.130 +
  19.131 +
  19.132 +<h1>Categorical Programs</h1>
  19.133 +
  19.134 +
  19.135 +<div id="table-of-contents">
  19.136 +<h2>Table of Contents</h2>
  19.137 +<div id="text-table-of-contents">
  19.138 +<ul>
  19.139 +<li><a href="#sec-1">1 The Category of Types </a>
  19.140 +<ul>
  19.141 +<li><a href="#sec-1-1">1.1 Building new data types out of existing ones </a></li>
  19.142 +</ul>
  19.143 +</li>
  19.144 +</ul>
  19.145 +</div>
  19.146 +</div>
  19.147 +
  19.148 +<div id="outline-container-1" class="outline-2">
  19.149 +<h2 id="sec-1"><span class="section-number-2">1</span> The Category of Types </h2>
  19.150 +<div class="outline-text-2" id="text-1">
  19.151 +
  19.152 +<p>Every computer language with data types (such as Integers,
  19.153 +Floats, or
  19.154 +Strings) corresponds with a certain category; the objects of the category are the data types
  19.155 +of the language, and there is one arrow between data types \(A\) and \(B\)
  19.156 +for every function in the language whose argument has type \(A\) and whose return value
  19.157 +has type \(B\). 
  19.158 +</p>
  19.159 +
  19.160 +
  19.161 +
  19.162 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">ns</span> categorical.morphisms)
  19.163 +
  19.164 +</pre>
  19.165 +
  19.166 +
  19.167 +
  19.168 +
  19.169 +
  19.170 +</div>
  19.171 +
  19.172 +<div id="outline-container-1-1" class="outline-3">
  19.173 +<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Building new data types out of existing ones </h3>
  19.174 +<div class="outline-text-3" id="text-1-1">
  19.175 +
  19.176 +
  19.177 +<p>
  19.178 +We will now discuss two processes which combine existing
  19.179 +data types to yield composite data types. These higher-order processes will be 
  19.180 +<i>functorial</i>, which means that they will recombine  not only the objects of
  19.181 +our category (the data types), but the arrows as well (functions with
  19.182 +typed input and output).
  19.183 +</p>
  19.184 +<p>
  19.185 +The <code>product</code> functor combines two data types, \(A\) and \(B\), producing
  19.186 +a new type, denoted \(A\times B\). Conceptually, values with the data type \(A\times
  19.187 +B\) have two components, the first of which is a value of type \(A\), the
  19.188 +second of which is a value of type \(B\). Concretely, the data type \(A\times B\)
  19.189 +can be implemented as pairs of values, the first of which is
  19.190 +of type \(A\) and the second of which is of type \(B\). With this
  19.191 +implementation in mind, you can see that the type \(A\) and type \(B\)
  19.192 +constituents of type \(A\times B\) value can be recovered; the so-called
  19.193 +projection functors <code>first</code> and <code>second</code> recover them. A third
  19.194 +functor, the <code>diagonal</code> functor, completes our toolkit; given
  19.195 +value \(a\) of type \(A\), it produces the value \((a,a)\) of type \(A\times A\).
  19.196 +</p>
  19.197 +
  19.198 +
  19.199 +
  19.200 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">product</span>[a b] (<span style="color: #8cd0d3;">list</span> a b))
  19.201 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">projections</span> (<span style="color: #8cd0d3;">list</span> first second))
  19.202 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">diagonal</span>[a] (product a a))
  19.203 +
  19.204 +</pre>
  19.205 +
  19.206 +
  19.207 +
  19.208 +
  19.209 +<p> 
  19.210 +The <code>coproduct</code> functor combines two data types, \(A\) and \(B\),
  19.211 +producing a new type, denoted \(A+B\). Conceptually, you construct the
  19.212 +\(A+B\) datatype by creating labelled versions of the data types \(A\) and
  19.213 +\(B\) &mdash; we'll call them black-\(A\) and white-\(B\) &mdash; and
  19.214 +then creating a data type \(A+B\) which contains all the black-\(A\)
  19.215 +values and all the white-\(B\) values. Concretely, you can implement the
  19.216 +\(A+B\) data type using label-value pairs: the first value in the pair
  19.217 +is either the label `black' or the label `white'; the second
  19.218 +value must have type \(A\) if the label is black, or type \(B\) if the
  19.219 +label is white. 
  19.220 +</p>
  19.221 +<p>
  19.222 +Now, the <code>product</code> functor came with projection functors <code>first</code>
  19.223 +and <code>second</code> that take \(A\times B\) values and return (respectively) \(A\) values and
  19.224 +\(B\) values. The <code>coproduct</code> functor, conversely, comes with two
  19.225 +injection functors <code>make-black</code> and <code>make-white</code> that perform the
  19.226 +opposite function: they take (respectively) \(A\) values and \(B\) values,
  19.227 +promoting them to the \(A+B\) datatype by making the \(A\)'s into
  19.228 +black-\(A\)'s and the \(B\)'s into white-\(B\)'s. 
  19.229 +</p>
  19.230 +
  19.231 +
  19.232 +</div>
  19.233 +</div>
  19.234 +</div>
  19.235 +<div id="postamble">
  19.236 +<p class="date">Date: 2011-07-01 12:28:39 CDT</p>
  19.237 +<p class="author">Author: Dylan Holmes</p>
  19.238 +<p class="creator">Org version 7.5 with Emacs version 23</p>
  19.239 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  19.240 +</div>
  19.241 +</div>
  19.242 +</body>
  19.243 +</html>
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/categorical/morphisms.org	Fri Oct 28 00:03:05 2011 -0700
    20.3 @@ -0,0 +1,81 @@
    20.4 +#+TITLE: Categorical Programs
    20.5 +#+AUTHOR: Dylan Holmes
    20.6 +
    20.7 +#+STYLE: <link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
    20.8 +
    20.9 +#+BEGIN_HTML
   20.10 +<h1>{{{title}}}</h1>
   20.11 +#+END_HTML
   20.12 +
   20.13 +* The Category of Types
   20.14 +Every computer language with data types (such as Integers,
   20.15 +Floats, or
   20.16 +Strings) corresponds with a certain category; the objects of the category are the data types
   20.17 +of the language, and there is one arrow between data types $A$ and $B$
   20.18 +for every function in the language whose argument has type $A$ and whose return value
   20.19 +has type $B$. 
   20.20 +
   20.21 +#+begin_src clojure :results silent
   20.22 +(ns categorical.morphisms)
   20.23 +#+end_src
   20.24 +
   20.25 +** Building new data types out of existing ones
   20.26 +
   20.27 +We will now discuss two processes which combine existing
   20.28 +data types to yield composite data types. These higher-order processes will be 
   20.29 +/functorial/, which means that they will recombine  not only the objects of
   20.30 +our category (the data types), but the arrows as well (functions with
   20.31 +typed input and output).
   20.32 +
   20.33 +The =product= functor combines two data types, $A$ and $B$, producing
   20.34 +a new type, denoted $A\times B$. Conceptually, values with the data type $A\times
   20.35 +B$ have two components, the first of which is a value of type $A$, the
   20.36 +second of which is a value of type $B$. Concretely, the data type $A\times B$
   20.37 +can be implemented as pairs of values, the first of which is
   20.38 +of type $A$ and the second of which is of type $B$. With this
   20.39 +implementation in mind, you can see that the type $A$ and type $B$
   20.40 +constituents of type $A\times B$ value can be recovered; the so-called
   20.41 +projection functors =first= and =second= recover them. A third
   20.42 +functor, the =diagonal= functor, completes our toolkit; given
   20.43 +value $a$ of type $A$, it produces the value $(a,a)$ of type $A\times A$.
   20.44 +
   20.45 +#+begin_src clojure :results silent
   20.46 +(defn product[a b] (list a b))
   20.47 +(def projections (list first second))
   20.48 +(defn diagonal[a] (product a a))
   20.49 +#+end_src
   20.50 + 
   20.51 +The =coproduct= functor combines two data types, $A$ and $B$,
   20.52 +producing a new type, denoted $A+B$. Conceptually, you construct the
   20.53 +$A+B$ datatype by creating labelled versions of the data types $A$ and
   20.54 +$B$ \mdash{} we'll call them black-$A$ and white-$B$ \mdash{} and
   20.55 +then creating a data type $A+B$ which contains all the black-$A$
   20.56 +values and all the white-$B$ values. Concretely, you can implement the
   20.57 +$A+B$ data type using label-value pairs: the first value in the pair
   20.58 +is either the label `black' or the label `white'; the second
   20.59 +value must have type $A$ if the label is black, or type $B$ if the
   20.60 +label is white. 
   20.61 +
   20.62 +Now, the =product= functor came with projection functors =first=
   20.63 +and =second= that take $A\times B$ values and return (respectively) $A$ values and
   20.64 +$B$ values. The =coproduct= functor, conversely, comes with two
   20.65 +injection functors =make-black= and =make-white= that perform the
   20.66 +opposite function: they take (respectively) $A$ values and $B$ values,
   20.67 +promoting them to the $A+B$ datatype by making the $A$'s into
   20.68 +black-$A$'s and the $B$'s into white-$B$'s. 
   20.69 +
   20.70 +#the =coproduct= functor comes with two injection functors =make-black=
   20.71 +#and =make-white=  that take (respectively) $A$ values and $B$ values,
   20.72 +#promoting them to the $A+B$ datatype by making them into black-$A$'s
   20.73 +#or white-$B$'s.
   20.74 +
   20.75 +
   20.76 +#The =coproduct= functor combines two data types, $A$ and $B$,
   20.77 +#producing a new type, denoted $A+B$. Conceptually, values with the
   20.78 +#data type $A+B$ can be either values with type $A$ that are designated /of the first
   20.79 +#kind/, or values with type $B$ that are designated /of the second
   20.80 +#kind/. Concretely, the data type $A+B$ can be implemented using pairs
   20.81 +#of values in conjunction with a labelling convention; the first value
   20.82 +#in the pair is of either type $A$ or $B$, and the second value is a label
   20.83 +#indicating whether it is of the first or second kind. Our labelling
   20.84 +#scheme uses the keywords =:black= and =:white= for this purpose.
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/categorical/plausible.html	Fri Oct 28 00:03:05 2011 -0700
    21.3 @@ -0,0 +1,336 @@
    21.4 +<?xml version="1.0" encoding="iso-8859-1"?>
    21.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    21.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    21.7 +<html xmlns="http://www.w3.org/1999/xhtml"
    21.8 +lang="en" xml:lang="en">
    21.9 +<head>
   21.10 +<title>Categorification of Plausible Reasoning</title>
   21.11 +<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
   21.12 +<meta name="generator" content="Org-mode"/>
   21.13 +<meta name="generated" content="2011-07-09 14:19:42 EDT"/>
   21.14 +<meta name="author" content="Dylan Holmes"/>
   21.15 +<meta name="description" content=""/>
   21.16 +<meta name="keywords" content=""/>
   21.17 +<style type="text/css">
   21.18 + <!--/*--><![CDATA[/*><!--*/
   21.19 +  html { font-family: Times, serif; font-size: 12pt; }
   21.20 +  .title  { text-align: center; }
   21.21 +  .todo   { color: red; }
   21.22 +  .done   { color: green; }
   21.23 +  .tag    { background-color: #add8e6; font-weight:normal }
   21.24 +  .target { }
   21.25 +  .timestamp { color: #bebebe; }
   21.26 +  .timestamp-kwd { color: #5f9ea0; }
   21.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
   21.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
   21.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
   21.30 +  p.verse { margin-left: 3% }
   21.31 +  pre {
   21.32 +	border: 1pt solid #AEBDCC;
   21.33 +	background-color: #F3F5F7;
   21.34 +	padding: 5pt;
   21.35 +	font-family: courier, monospace;
   21.36 +        font-size: 90%;
   21.37 +        overflow:auto;
   21.38 +  }
   21.39 +  table { border-collapse: collapse; }
   21.40 +  td, th { vertical-align: top;  }
   21.41 +  th.right  { text-align:center;  }
   21.42 +  th.left   { text-align:center;   }
   21.43 +  th.center { text-align:center; }
   21.44 +  td.right  { text-align:right;  }
   21.45 +  td.left   { text-align:left;   }
   21.46 +  td.center { text-align:center; }
   21.47 +  dt { font-weight: bold; }
   21.48 +  div.figure { padding: 0.5em; }
   21.49 +  div.figure p { text-align: center; }
   21.50 +  textarea { overflow-x: auto; }
   21.51 +  .linenr { font-size:smaller }
   21.52 +  .code-highlighted {background-color:#ffff00;}
   21.53 +  .org-info-js_info-navigation { border-style:none; }
   21.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
   21.55 +                               white-space:nowrap; }
   21.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
   21.57 +                                 font-weight:bold; }
   21.58 +  /*]]>*/-->
   21.59 +</style>
   21.60 +<script type="text/javascript">
   21.61 +<!--/*--><![CDATA[/*><!--*/
   21.62 + function CodeHighlightOn(elem, id)
   21.63 + {
   21.64 +   var target = document.getElementById(id);
   21.65 +   if(null != target) {
   21.66 +     elem.cacheClassElem = elem.className;
   21.67 +     elem.cacheClassTarget = target.className;
   21.68 +     target.className = "code-highlighted";
   21.69 +     elem.className   = "code-highlighted";
   21.70 +   }
   21.71 + }
   21.72 + function CodeHighlightOff(elem, id)
   21.73 + {
   21.74 +   var target = document.getElementById(id);
   21.75 +   if(elem.cacheClassElem)
   21.76 +     elem.className = elem.cacheClassElem;
   21.77 +   if(elem.cacheClassTarget)
   21.78 +     target.className = elem.cacheClassTarget;
   21.79 + }
   21.80 +/*]]>*///-->
   21.81 +</script>
   21.82 +<script type="text/javascript" src="../MathJax/MathJax.js">
   21.83 +<!--/*--><![CDATA[/*><!--*/
   21.84 +    MathJax.Hub.Config({
   21.85 +        // Only one of the two following lines, depending on user settings
   21.86 +        // First allows browser-native MathML display, second forces HTML/CSS
   21.87 +            config: ["MMLorHTML.js"], jax: ["input/TeX"],
   21.88 +        //  jax: ["input/TeX", "output/HTML-CSS"],
   21.89 +        extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js",
   21.90 +                     "TeX/noUndefined.js"],
   21.91 +        tex2jax: {
   21.92 +            inlineMath: [ ["\\(","\\)"] ],
   21.93 +            displayMath: [ ['$$','$$'], ["\\[","\\]"], ["\\begin{displaymath}","\\end{displaymath}"] ],
   21.94 +            skipTags: ["script","noscript","style","textarea","pre","code"],
   21.95 +            ignoreClass: "tex2jax_ignore",
   21.96 +            processEscapes: false,
   21.97 +            processEnvironments: true,
   21.98 +            preview: "TeX"
   21.99 +        },
  21.100 +        showProcessingMessages: true,
  21.101 +        displayAlign: "left",
  21.102 +        displayIndent: "2em",
  21.103 +
  21.104 +        "HTML-CSS": {
  21.105 +             scale: 100,
  21.106 +             availableFonts: ["STIX","TeX"],
  21.107 +             preferredFont: "TeX",
  21.108 +             webFont: "TeX",
  21.109 +             imageFont: "TeX",
  21.110 +             showMathMenu: true,
  21.111 +        },
  21.112 +        MMLorHTML: {
  21.113 +             prefer: {
  21.114 +                 MSIE:    "MML",
  21.115 +                 Firefox: "MML",
  21.116 +                 Opera:   "HTML",
  21.117 +                 other:   "HTML"
  21.118 +             }
  21.119 +        }
  21.120 +    });
  21.121 +/*]]>*///-->
  21.122 +</script>
  21.123 +</head>
  21.124 +<body>
  21.125 +<div id="content">
  21.126 +
  21.127 +
  21.128 +
  21.129 +
  21.130 +<div id="table-of-contents">
  21.131 +<h2>Table of Contents</h2>
  21.132 +<div id="text-table-of-contents">
  21.133 +<ul>
  21.134 +<li><a href="#sec-1">1 Deductive and inductive posets </a>
  21.135 +<ul>
  21.136 +<li><a href="#sec-1-1">1.1 Definition </a></li>
  21.137 +<li><a href="#sec-1-2">1.2 A canonical map from  deductive posets to inductive posets </a></li>
  21.138 +</ul>
  21.139 +</li>
  21.140 +<li><a href="#sec-2">2 Assigning plausibilities to inductive posets </a>
  21.141 +<ul>
  21.142 +<li><a href="#sec-2-1">2.1 Consistent reasoning as a commutative diagram </a></li>
  21.143 +<li><a href="#sec-2-2">2.2 ``Multiplicity'' is reciprocal probability </a></li>
  21.144 +<li><a href="#sec-2-3">2.3 Laws for multiplicity </a></li>
  21.145 +</ul>
  21.146 +</li>
  21.147 +</ul>
  21.148 +</div>
  21.149 +</div>
  21.150 +
  21.151 +<div id="outline-container-1" class="outline-2">
  21.152 +<h2 id="sec-1"><span class="section-number-2">1</span> Deductive and inductive posets </h2>
  21.153 +<div class="outline-text-2" id="text-1">
  21.154 +
  21.155 +
  21.156 +
  21.157 +</div>
  21.158 +
  21.159 +<div id="outline-container-1-1" class="outline-3">
  21.160 +<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Definition </h3>
  21.161 +<div class="outline-text-3" id="text-1-1">
  21.162 +
  21.163 +<p>If you have a collection \(P\) of logical propositions, you can order them by
  21.164 +implication: \(a\) precedes \(b\) if and only if \(a\) implies
  21.165 +\(b\). This makes \(P\) into a poset. Since the ordering arose from
  21.166 +deductive implication, we'll call this a <i>deductive poset</i>.
  21.167 +</p>
  21.168 +<p>
  21.169 +If you have a deductive poset \(P\),  you can create a related poset \(P^*\)
  21.170 +as follows: the underlying set is the same, and for any two
  21.171 +propositions \(a\) and \(b\) in \(P\), \(a\) precedes
  21.172 +\(ab\) in \(P^*\). We'll call this an <i>inductive poset</i>.
  21.173 +</p>
  21.174 +</div>
  21.175 +
  21.176 +</div>
  21.177 +
  21.178 +<div id="outline-container-1-2" class="outline-3">
  21.179 +<h3 id="sec-1-2"><span class="section-number-3">1.2</span> A canonical map from  deductive posets to inductive posets </h3>
  21.180 +<div class="outline-text-3" id="text-1-2">
  21.181 +
  21.182 +<p>Each poset corresponds with a poset-category, that is a category with
  21.183 +at most one arrow between any two objects. Considered as categories,
  21.184 +inductive and deuctive posets are related as follows: there is a map
  21.185 +\(\mathscr{F}\) which sends each arrow \(a\rightarrow b\) in \(P\) to
  21.186 +the arrow \(a\rightarrow ab\) in \(P^*\). In fact, since \(a\) implies
  21.187 +\(b\) if and only if \(a = ab\), \(\mathscr{F}\) sends each arrow  in \(P\) to
  21.188 +an identity arrow  in \(P^*\) (specifically, it sends the arrow
  21.189 +\(a\rightarrow b\) to the identity arrow \(a\rightarrow a\)).
  21.190 +</p>
  21.191 +
  21.192 +</div>
  21.193 +</div>
  21.194 +
  21.195 +</div>
  21.196 +
  21.197 +<div id="outline-container-2" class="outline-2">
  21.198 +<h2 id="sec-2"><span class="section-number-2">2</span> Assigning plausibilities to inductive posets </h2>
  21.199 +<div class="outline-text-2" id="text-2">
  21.200 +
  21.201 +
  21.202 +<p>
  21.203 +Inductive posets encode the relative (<i>qualitative</i>) plausibilities of its
  21.204 +propositions: there exists an arrow \(x\rightarrow y\) only if \(x\)
  21.205 +is at least as plausible as \(y\).
  21.206 +</p>
  21.207 +
  21.208 +</div>
  21.209 +
  21.210 +<div id="outline-container-2-1" class="outline-3">
  21.211 +<h3 id="sec-2-1"><span class="section-number-3">2.1</span> Consistent reasoning as a commutative diagram </h3>
  21.212 +<div class="outline-text-3" id="text-2-1">
  21.213 +
  21.214 +<p>Inductive categories enable the following neat trick: we can interpret
  21.215 +the objects of \(P^*\) as states of given information and interpret
  21.216 +each arrow \(a\rightarrow ab\) in \(P^*\) as an inductive inference: the arrow
  21.217 +\(a\rightarrow ab\) represents an inferential leap from the state of
  21.218 +knowledge where only \(a\) is given to the state of knowledge where
  21.219 +both \(a\) and \(b\) are given&mdash; in this way, it represents
  21.220 +the process of inferring \(b\) when  given \(a\), and we label the
  21.221 +arrow with \((b|a)\).
  21.222 +</p>
  21.223 +<p>
  21.224 +This trick has several important features that suggest its usefulness,
  21.225 +namely
  21.226 +</p><ul>
  21.227 +<li>Composition of arrows corresponds to compound inference.
  21.228 +</li>
  21.229 +<li>In the special case of deductive inference, the inferential arrow is an
  21.230 +   identity; the source and destination states of knowledge are the same.
  21.231 +</li>
  21.232 +<li>One aspect of the consistency requirement of Jaynes<sup><a class="footref" name="fnr.1" href="#fn.1">1</a></sup> takes the form of a
  21.233 +   commutative square: \(x\rightarrow ax \rightarrow abx\) =
  21.234 +   \(x\rightarrow bx \rightarrow abx\) is the categorified version of
  21.235 +   \((AB|X)=(A|X)\cdot(B|AX)=(B|X)\cdot(A|BX)\).
  21.236 +</li>
  21.237 +<li>We can make plausibility assignments by enriching the inductive
  21.238 +   category \(P^*\) over some monoidal category, e.g. the set of real numbers
  21.239 +   (considered as a category) with its usual multiplication. <i>When we do</i>,
  21.240 +   the identity arrows of \(P^*\) &mdash;corresponding to
  21.241 +   deductive inferences&mdash; are assigned a value of certainty automatically.
  21.242 +</li>
  21.243 +</ul>
  21.244 +
  21.245 +
  21.246 +</div>
  21.247 +
  21.248 +</div>
  21.249 +
  21.250 +<div id="outline-container-2-2" class="outline-3">
  21.251 +<h3 id="sec-2-2"><span class="section-number-3">2.2</span> ``Multiplicity'' is reciprocal probability </h3>
  21.252 +<div class="outline-text-3" id="text-2-2">
  21.253 +
  21.254 +<p>The natural numbers have a comparatively concrete origin: they are the
  21.255 +result of decategorifying the category of finite sets<sup><a class="footref" name="fnr.2" href="#fn.2">2</a></sup>, or the
  21.256 +coequalizer of the arrows from a one-object category to a two-object
  21.257 +category with a single nonidentity arrow. Extensions of the set of
  21.258 +natural numbers&mdash; such as
  21.259 +the set of integers or rational numbers or real numbers&mdash; strike
  21.260 +me as being somewhat more abstract (however, see the Eudoxus
  21.261 +construction of the real numbers).
  21.262 +</p>
  21.263 +<p>
  21.264 +Jaynes points out that our existing choice of scale for probabilities
  21.265 +(i.e., the scale from 0 for impossibility to 1 for
  21.266 +certainty) has a degree of freedom: any monotonic function of
  21.267 +probability encodes the same information that probability does. Though
  21.268 +the resulting laws for compound probability and so on change in form
  21.269 +when probabilities are changed, they do not change in content. 
  21.270 +</p>
  21.271 +<p>
  21.272 +With this in mind, it seems natural  and permissible to use not <i>probability</i> but
  21.273 +<i>reciprocal probability</i> instead. This scale, which we might
  21.274 + call <i>multiplicity</i>, ranges from 1 (certainty) to
  21.275 +positive infinity (impossibility); higher numbers are ascribed to
  21.276 +less-plausible events.
  21.277 +</p>
  21.278 +<p>
  21.279 +In this way, the ``probability''
  21.280 +associated with choosing one out of \(n\) indistinguishable choices
  21.281 +becomes identified with \(n\).
  21.282 +</p>
  21.283 +</div>
  21.284 +
  21.285 +</div>
  21.286 +
  21.287 +<div id="outline-container-2-3" class="outline-3">
  21.288 +<h3 id="sec-2-3"><span class="section-number-3">2.3</span> Laws for multiplicity </h3>
  21.289 +<div class="outline-text-3" id="text-2-3">
  21.290 +
  21.291 +<p>Jaynes derives laws of probability; either his method or his results
  21.292 +can be used to obtain laws for multiplicities.
  21.293 +</p>
  21.294 +<dl>
  21.295 +<dt>product rule</dt><dd>The product rule is unchanged: \(\xi(AB|X)=\xi(A|X)\cdot
  21.296 +                   \xi(B|AX) = \xi(B|X)\cdot \xi(A|BX)\)
  21.297 +</dd>
  21.298 +<dt>certainty</dt><dd>States of absolute certainty are assigned a multiplicity
  21.299 +                of 1. States of absolute impossibility are assigned a
  21.300 +                multiplicity of positive infinity.
  21.301 +</dd>
  21.302 +<dt>entropy</dt><dd>In terms of probability, entropy has the form \(S=-\sum_i
  21.303 +              p_i \ln{p_i} = \sum_i p_i (-\ln{p_i}) = \sum_i p_i \ln{(1/p_i)}
  21.304 +              \). Hence, in terms of multiplicity, entropy
  21.305 +              has the form \(S = \sum_i \frac{\ln{\xi_i}}{\xi_i} \).
  21.306 +
  21.307 +<p>
  21.308 +              Another interesting quantity is \(\exp{S}\), which behaves
  21.309 +              multiplicitively rather than additively. \(\exp{S} =
  21.310 +              \prod_i \exp{\frac{\ln{\xi_i}}{\xi_i}} =
  21.311 +              \left(\exp{\ln{\xi_i}}\right)^{1/\xi_i} =  \prod_i \xi_i^{1/\xi_i} \)
  21.312 +</p></dd>
  21.313 +</dl>
  21.314 +
  21.315 +
  21.316 +
  21.317 +<div id="footnotes">
  21.318 +<h2 class="footnotes">Footnotes: </h2>
  21.319 +<div id="text-footnotes">
  21.320 +<p class="footnote"><sup><a class="footnum" name="fn.1" href="#fnr.1">1</a></sup> <i>(IIIa) If a conclusion can be reasoned out in more than one way, then every possible way must lead to the same result.</i>
  21.321 +</p>
  21.322 +
  21.323 +<p class="footnote"><sup><a class="footnum" name="fn.2" href="#fnr.2">2</a></sup> As Baez explains.
  21.324 +</p>
  21.325 +</div>
  21.326 +</div>
  21.327 +</div>
  21.328 +
  21.329 +</div>
  21.330 +</div>
  21.331 +<div id="postamble">
  21.332 +<p class="date">Date: 2011-07-09 14:19:42 EDT</p>
  21.333 +<p class="author">Author: Dylan Holmes</p>
  21.334 +<p class="creator">Org version 7.6 with Emacs version 23</p>
  21.335 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  21.336 +</div>
  21.337 +</div>
  21.338 +</body>
  21.339 +</html>
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/categorical/plausible.org	Fri Oct 28 00:03:05 2011 -0700
    22.3 @@ -0,0 +1,114 @@
    22.4 +#+TITLE: Categorification of Plausible Reasoning
    22.5 +#+AUTHOR: Dylan Holmes
    22.6 +#+MATHJAX: align:"left" mathml:t path:"../MathJax/MathJax.js"
    22.7 +* COMMENT #+OPTIONS: LaTeX:dvipng
    22.8 +
    22.9 +* Deductive and inductive posets
   22.10 +
   22.11 +** Definition
   22.12 +If you have a collection \(P\) of logical propositions, you can order them by
   22.13 +implication: \(a\) precedes \(b\) if and only if \(a\) implies
   22.14 +\(b\). This makes \(P\) into a poset. Since the ordering arose from
   22.15 +deductive implication, we'll call this a /deductive poset/.
   22.16 +
   22.17 +If you have a deductive poset \(P\),  you can create a related poset \(P^*\)
   22.18 +as follows: the underlying set is the same, and for any two
   22.19 +propositions \(a\) and \(b\) in \(P\), \(a\) precedes
   22.20 +\(ab\) in \(P^*\). We'll call this an /inductive poset/.
   22.21 +
   22.22 +** A canonical map from  deductive posets to inductive posets
   22.23 +Each poset corresponds with a poset-category, that is a category with
   22.24 +at most one arrow between any two objects. Considered as categories,
   22.25 +inductive and deuctive posets are related as follows: there is a map
   22.26 +\(\mathscr{F}\) which sends each arrow \(a\rightarrow b\) in \(P\) to
   22.27 +the arrow \(a\rightarrow ab\) in \(P^*\). In fact, since \(a\) implies
   22.28 +\(b\) if and only if \(a = ab\), \(\mathscr{F}\) sends each arrow  in \(P\) to
   22.29 +an identity arrow  in \(P^*\) (specifically, it sends the arrow
   22.30 +\(a\rightarrow b\) to the identity arrow \(a\rightarrow a\)).
   22.31 +
   22.32 +
   22.33 +** Assigning plausibilities to inductive posets
   22.34 +
   22.35 +Inductive posets encode the relative (/qualitative/) plausibilities of its
   22.36 +propositions: there exists an arrow \(x\rightarrow y\) only if \(x\)
   22.37 +is at least as plausible as \(y\).
   22.38 +
   22.39 +*** Consistent reasoning as a commutative diagram
   22.40 +Inductive categories enable the following neat trick: we can interpret
   22.41 +the objects of \(P^*\) as states of given information and interpret
   22.42 +each arrow \(a\rightarrow ab\) in \(P^*\) as an inductive inference: the arrow
   22.43 +\(a\rightarrow ab\) represents an inferential leap from the state of
   22.44 +knowledge where only \(a\) is given to the state of knowledge where
   22.45 +both \(a\) and \(b\) are given\mdash{} in this way, it represents
   22.46 +the process of inferring \(b\) when  given \(a\), and we label the
   22.47 +arrow with \((b|a)\).
   22.48 +
   22.49 +This trick has several important features that suggest its usefulness,
   22.50 +namely
   22.51 + - Composition of arrows corresponds to compound inference.
   22.52 + - In the special case of deductive inference, the inferential arrow is an
   22.53 +   identity; the source and destination states of knowledge are the same.
   22.54 + - One aspect of the consistency requirement of Jaynes[fn:1] takes the form of a
   22.55 +   commutative square: \(x\rightarrow ax \rightarrow abx\) =
   22.56 +   \(x\rightarrow bx \rightarrow abx\) is the categorified version of
   22.57 +   \((AB|X)=(A|X)\cdot(B|AX)=(B|X)\cdot(A|BX)\).
   22.58 + - We can make plausibility assignments by enriching the inductive
   22.59 +   category \(P^*\) over some monoidal category, e.g. the set of real numbers
   22.60 +   (considered as a category) with its usual multiplication. /When we do/,
   22.61 +   the identity arrows of \(P^*\) \mdash{}corresponding to
   22.62 +   deductive inferences\mdash{} are assigned a value of certainty automatically.
   22.63 +
   22.64 +[fn:1] /(IIIa) If a conclusion can be reasoned out in more than one
   22.65 +way, then every possible way must lead to the same result./
   22.66 +
   22.67 +
   22.68 +*** Reciprocal probabilities
   22.69 +The natural numbers have a comparatively concrete origin: they are the
   22.70 +result of decategorifying the category of finite sets[fn:2], or the
   22.71 +coequalizer of the arrows from a one-object category to a two-object
   22.72 +category with a single nonidentity arrow. Extensions of the set of
   22.73 +natural numbers\mdash{} such as
   22.74 +the set of integers or rational numbers or real numbers\mdash{} strike
   22.75 +me as being somewhat more abstract.
   22.76 +
   22.77 +Jaynes points out that our existing choice of scale for probabilities
   22.78 +(i.e., the scale from 0 for impossibility to 1 for
   22.79 +certainty) has a degree of freedom: any monotonic function of
   22.80 +probability encodes the same information that probability does.
   22.81 +
   22.82 +With this in mind, it seems useful to use not /probability/ but
   22.83 +/reciprocal probability/ instead. This scale, which we might
   22.84 +tentatively call freeness, is a scale ranging 1 (certainty) to
   22.85 +positive infinity (impossibility).
   22.86 +
   22.87 +In this way, the ``probability''
   22.88 +associated with choosing one out of \(n\) indistinguishable choices
   22.89 +becomes identified with \(n\).
   22.90 +
   22.91 +The entropy 
   22.92 +
   22.93 +[fn:2] As Baez says.
   22.94 +
   22.95 +
   22.96 +
   22.97 +** self-questions
   22.98 +
   22.99 +What circumstances would make \(\mathscr{F}\) an injection?
  22.100 +
  22.101 +What if \(P=\{\top,\bot\}\)?
  22.102 +
  22.103 +
  22.104 +
  22.105 +** COMMENT 
  22.106 +Inductive and deductive posets are related as follows: there is a monotone
  22.107 +inclusion map \(\mathscr{i}:P^*\hookrightarrow P\) which\mdash{} since \(a\)
  22.108 +implies \(b\) is equivalent to \(a=ab\)\mdash{} sends comparable
  22.109 +propositions in \(P\) to the same proposition in \(P^*\). Conversely,
  22.110 +only comparable propositions in \(P\) are sent to the same proposition
  22.111 +in \(P^*\).
  22.112 +
  22.113 +
  22.114 +
  22.115 +** Inductive posets and plausibility
  22.116 +
  22.117 +* Inverse Probability
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/categorical/plausible.org_archive	Fri Oct 28 00:03:05 2011 -0700
    23.3 @@ -0,0 +1,40 @@
    23.4 +#    -*- mode: org -*-
    23.5 +
    23.6 +
    23.7 +Archived entries from file /home/r/aurellem/src/categorical/plausible.org
    23.8 +
    23.9 +* Consistent reasoning as a commutative diagram
   23.10 +  :PROPERTIES:
   23.11 +  :ARCHIVE_TIME: 2011-07-09 Sat 01:00
   23.12 +  :ARCHIVE_FILE: ~/aurellem/src/categorical/plausible.org
   23.13 +  :ARCHIVE_OLPATH: Deductive and inductive posets/Assigning plausibilities to inductive posets
   23.14 +  :ARCHIVE_CATEGORY: plausible
   23.15 +  :END:
   23.16 +Inductive categories enable the following neat trick: we can interpret
   23.17 +the objects of \(P^*\) as states of given information and interpret
   23.18 +each arrow \(a\rightarrow ab\) in \(P^*\) as an inductive inference: the arrow
   23.19 +\(a\rightarrow ab\) represents an inferential leap from the state of
   23.20 +knowledge where only \(a\) is given to the state of knowledge where
   23.21 +both \(a\) and \(b\) are given\mdash{} in this way, it represents
   23.22 +the process of inferring \(b\) when  given \(a\), and we label the
   23.23 +arrow with \((b|a)\).
   23.24 +
   23.25 +This trick has several important features that suggest its usefulness,
   23.26 +namely
   23.27 + - Composition of arrows corresponds to compound inference.
   23.28 + - In the special case of deductive inference, the inferential arrow is an
   23.29 +   identity; the source and destination states of knowledge are the same.
   23.30 + - One aspect of the consistency requirement of Jaynes[fn:1] takes the form of a
   23.31 +   commutative square: \(x\rightarrow ax \rightarrow abx\) =
   23.32 +   \(x\rightarrow bx \rightarrow abx\) is the categorified version of
   23.33 +   \((AB|X)=(A|X)\cdot(B|AX)=(B|X)\cdot(A|BX)\).
   23.34 + - We can make plausibility assignments by enriching the inductive
   23.35 +   category \(P^*\) over some monoidal category, e.g. the set of real numbers
   23.36 +   (considered as a category) with its usual multiplication. /When we do/,
   23.37 +   the identity arrows of \(P^*\) \mdash{}corresponding to
   23.38 +   deductive inferences\mdash{} are assigned a value of certainty automatically.
   23.39 +
   23.40 +[fn:1] /(IIIa) If a conclusion can be reasoned out in more than one
   23.41 +way, then every possible way must lead to the same result./
   23.42 +
   23.43 +
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/categorical/synthetic.html	Fri Oct 28 00:03:05 2011 -0700
    24.3 @@ -0,0 +1,282 @@
    24.4 +<?xml version="1.0" encoding="utf-8"?>
    24.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    24.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    24.7 +<html xmlns="http://www.w3.org/1999/xhtml"
    24.8 +lang="en" xml:lang="en">
    24.9 +<head>
   24.10 +<title>Synthetic Differential Geometry</title>
   24.11 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
   24.12 +<meta name="generator" content="Org-mode"/>
   24.13 +<meta name="generated" content="2011-08-15 22:42:41 EDT"/>
   24.14 +<meta name="author" content="Dylan Holmes"/>
   24.15 +<meta name="description" content=""/>
   24.16 +<meta name="keywords" content=""/>
   24.17 +<style type="text/css">
   24.18 + <!--/*--><![CDATA[/*><!--*/
   24.19 +  html { font-family: Times, serif; font-size: 12pt; }
   24.20 +  .title  { text-align: center; }
   24.21 +  .todo   { color: red; }
   24.22 +  .done   { color: green; }
   24.23 +  .tag    { background-color: #add8e6; font-weight:normal }
   24.24 +  .target { }
   24.25 +  .timestamp { color: #bebebe; }
   24.26 +  .timestamp-kwd { color: #5f9ea0; }
   24.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
   24.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
   24.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
   24.30 +  p.verse { margin-left: 3% }
   24.31 +  pre {
   24.32 +	border: 1pt solid #AEBDCC;
   24.33 +	background-color: #F3F5F7;
   24.34 +	padding: 5pt;
   24.35 +	font-family: courier, monospace;
   24.36 +        font-size: 90%;
   24.37 +        overflow:auto;
   24.38 +  }
   24.39 +  table { border-collapse: collapse; }
   24.40 +  td, th { vertical-align: top;  }
   24.41 +  th.right  { text-align:center;  }
   24.42 +  th.left   { text-align:center;   }
   24.43 +  th.center { text-align:center; }
   24.44 +  td.right  { text-align:right;  }
   24.45 +  td.left   { text-align:left;   }
   24.46 +  td.center { text-align:center; }
   24.47 +  dt { font-weight: bold; }
   24.48 +  div.figure { padding: 0.5em; }
   24.49 +  div.figure p { text-align: center; }
   24.50 +  textarea { overflow-x: auto; }
   24.51 +  .linenr { font-size:smaller }
   24.52 +  .code-highlighted {background-color:#ffff00;}
   24.53 +  .org-info-js_info-navigation { border-style:none; }
   24.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
   24.55 +                               white-space:nowrap; }
   24.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
   24.57 +                                 font-weight:bold; }
   24.58 +  /*]]>*/-->
   24.59 +</style>
   24.60 +<link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
   24.61 +<script type="text/javascript">
   24.62 +<!--/*--><![CDATA[/*><!--*/
   24.63 + function CodeHighlightOn(elem, id)
   24.64 + {
   24.65 +   var target = document.getElementById(id);
   24.66 +   if(null != target) {
   24.67 +     elem.cacheClassElem = elem.className;
   24.68 +     elem.cacheClassTarget = target.className;
   24.69 +     target.className = "code-highlighted";
   24.70 +     elem.className   = "code-highlighted";
   24.71 +   }
   24.72 + }
   24.73 + function CodeHighlightOff(elem, id)
   24.74 + {
   24.75 +   var target = document.getElementById(id);
   24.76 +   if(elem.cacheClassElem)
   24.77 +     elem.className = elem.cacheClassElem;
   24.78 +   if(elem.cacheClassTarget)
   24.79 +     target.className = elem.cacheClassTarget;
   24.80 + }
   24.81 +/*]]>*///-->
   24.82 +</script>
   24.83 +<script type="text/javascript" src="../MathJax/MathJax.js">
   24.84 +<!--/*--><![CDATA[/*><!--*/
   24.85 +    MathJax.Hub.Config({
   24.86 +        // Only one of the two following lines, depending on user settings
   24.87 +        // First allows browser-native MathML display, second forces HTML/CSS
   24.88 +            config: ["MMLorHTML.js"], jax: ["input/TeX"],
   24.89 +        //  jax: ["input/TeX", "output/HTML-CSS"],
   24.90 +        extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js",
   24.91 +                     "TeX/noUndefined.js"],
   24.92 +        tex2jax: {
   24.93 +            inlineMath: [ ["\\(","\\)"] ],
   24.94 +            displayMath: [ ['$$','$$'], ["\\[","\\]"], ["\\begin{displaymath}","\\end{displaymath}"] ],
   24.95 +            skipTags: ["script","noscript","style","textarea","pre","code"],
   24.96 +            ignoreClass: "tex2jax_ignore",
   24.97 +            processEscapes: false,
   24.98 +            processEnvironments: true,
   24.99 +            preview: "TeX"
  24.100 +        },
  24.101 +        showProcessingMessages: true,
  24.102 +        displayAlign: "left",
  24.103 +        displayIndent: "2em",
  24.104 +
  24.105 +        "HTML-CSS": {
  24.106 +             scale: 100,
  24.107 +             availableFonts: ["STIX","TeX"],
  24.108 +             preferredFont: "TeX",
  24.109 +             webFont: "TeX",
  24.110 +             imageFont: "TeX",
  24.111 +             showMathMenu: true,
  24.112 +        },
  24.113 +        MMLorHTML: {
  24.114 +             prefer: {
  24.115 +                 MSIE:    "MML",
  24.116 +                 Firefox: "MML",
  24.117 +                 Opera:   "HTML",
  24.118 +                 other:   "HTML"
  24.119 +             }
  24.120 +        }
  24.121 +    });
  24.122 +/*]]>*///-->
  24.123 +</script>
  24.124 +</head>
  24.125 +<body>
  24.126 +
  24.127 +<div id="content">
  24.128 +
  24.129 +
  24.130 +
  24.131 +<div class="header">
  24.132 +  <div class="float-right">	
  24.133 +    <!-- 
  24.134 +    <form>
  24.135 +      <input type="text"/><input type="submit" value="search the blog &raquo;"/> 
  24.136 +    </form>
  24.137 +    -->
  24.138 +  </div>
  24.139 +
  24.140 +  <h1>aurellem <em>&#x2609;</em></h1>
  24.141 +  <ul class="nav">
  24.142 +    <li><a href="/">read the blog &raquo;</a></li>
  24.143 +    <!-- li><a href="#">learn about us &raquo;</a></li-->
  24.144 +  </ul>
  24.145 +</div>
  24.146 +
  24.147 +<h1 class="title">Synthetic Differential Geometry</h1>
  24.148 +<div class="author">Written by <author>Dylan Holmes</author></div>
  24.149 +
  24.150 +
  24.151 +
  24.152 +
  24.153 +
  24.154 +
  24.155 +<p>
  24.156 +(My notes on Anders Kock's <i>Synthetic Differential Geometry</i>)
  24.157 +</p>
  24.158 +
  24.159 +<div id="table-of-contents">
  24.160 +<h2>Table of Contents</h2>
  24.161 +<div id="text-table-of-contents">
  24.162 +<ul>
  24.163 +<li><a href="#sec-1">1 Revisiting the real line </a>
  24.164 +<ul>
  24.165 +<li><a href="#sec-1-1">1.1 The first anti-euclidean axiom </a></li>
  24.166 +<li><a href="#sec-1-2">1.2 The first axiom \(\ldots\) in terms of arrows </a></li>
  24.167 +<li><a href="#sec-1-3">1.3 Ex </a></li>
  24.168 +</ul>
  24.169 +</li>
  24.170 +</ul>
  24.171 +</div>
  24.172 +</div>
  24.173 +
  24.174 +<div id="outline-container-1" class="outline-2">
  24.175 +<h2 id="sec-1"><span class="section-number-2">1</span> Revisiting the real line </h2>
  24.176 +<div class="outline-text-2" id="text-1">
  24.177 +
  24.178 +
  24.179 +<p>
  24.180 +<b>Lines</b>, the kind which Euclid talked about, each constitute a commutative
  24.181 + ring: you choose any two points on the line to be 0 and 1, then add
  24.182 + and multiply as if you were dealing with real numbers \(\mathbb{R}\).
  24.183 +</p>
  24.184 +<p>
  24.185 +Euclid moreover uses the axiom that for any two points, <i>either</i> they are the
  24.186 +same point <i>or</i> there is a unique line between them. Algebraically,
  24.187 +this amounts to saying that each line is not only a commutative ring
  24.188 +but a <b>field</b>, as well. This marks our first departure from euclidean
  24.189 +geometry, as our first axiom denies that each line is a field.
  24.190 +</p>
  24.191 +
  24.192 +
  24.193 +</div>
  24.194 +
  24.195 +<div id="outline-container-1-1" class="outline-3">
  24.196 +<h3 id="sec-1-1"><span class="section-number-3">1.1</span> The first anti-euclidean axiom </h3>
  24.197 +<div class="outline-text-3" id="text-1-1">
  24.198 +
  24.199 +<p>A point in a ring is called <b>nilpotent</b> if its square is
  24.200 +zero. Normally (that is, in \(\mathbb{R}^n\)), only \(0\) is
  24.201 +nilpotent. Here, as a consequence of the following axiom, there will
  24.202 +exist other elements that are nilpotent. These elements will
  24.203 +encapsulate our intuitive idea of &ldquo;infinitesimally small&rdquo; numbers.
  24.204 +</p>
  24.205 +<blockquote>
  24.206 +
  24.207 +<p><b>Axiom 1:</b> Let \(R\) be the line, considered as a commutative ring, and
  24.208 + let \(D\subset R\) be the set of nilpotent elements on the line. Then for any
  24.209 + morphism \(g:D\rightarrow R\), there exists a unique \(b\in R\) such that
  24.210 +</p>
  24.211 +
  24.212 +
  24.213 +\(\forall d\in D, g(d) = g(0)+ b\cdot d\)
  24.214 +
  24.215 +<p>
  24.216 +Intuitively, this unique \(b\) is the slope of the function \(g\) near
  24.217 +zero. Because every morphism \(g\) has exactly one such \(b\), we have the
  24.218 +following results:
  24.219 +</p>
  24.220 +<ol>
  24.221 +<li>The set \(D\) of nilpotent elements contains more than
  24.222 +   just 0. Indeed, suppose the contrary: if \(D=\{0\}\), then for any \(g\), <i>every</i> \(b\in R\) has the
  24.223 +   property described above;&mdash;\(b\) isn't uniquely defined.
  24.224 +</li>
  24.225 +<li>Pick \(b_1\) and \(b_2\) in \(R\). If every nilpotent \(d\) satisfies \(d\cdot
  24.226 +   b_1 = d\cdot b_2\), then \(b_1\) and \(b_2\) are equal.
  24.227 +</li>
  24.228 +</ol>
  24.229 +
  24.230 +
  24.231 +</div>
  24.232 +
  24.233 +</div>
  24.234 +
  24.235 +<div id="outline-container-1-2" class="outline-3">
  24.236 +<h3 id="sec-1-2"><span class="section-number-3">1.2</span> The first axiom \(\ldots\) in terms of arrows </h3>
  24.237 +<div class="outline-text-3" id="text-1-2">
  24.238 +
  24.239 +
  24.240 +<p>
  24.241 +Define \(\xi:R\times R\rightarrow R^D\) by \(\xi:(a,b)\mapsto (d\mapsto
  24.242 +a+b\cdot d)\). The first axiom is equivalent to the statement
  24.243 +&ldquo;&xi; is invertible (i.e., a bijection)&rdquo;
  24.244 +</p>
  24.245 +<p>
  24.246 +We give \(R\times R\) the structure of an \(R\)-algebra by defining
  24.247 +multiplication: \( (a_1,b_1)\star(a_2,b_2) = (a_1\cdot a_2,\quad
  24.248 +a_1\cdot b_2 + a_2\cdot b_1)\). This is called <b>dual-numbers multiplication</b>, and is similar to muliplication of complex numbers.
  24.249 +</p>
  24.250 +
  24.251 +</div>
  24.252 +
  24.253 +</div>
  24.254 +
  24.255 +<div id="outline-container-1-3" class="outline-3">
  24.256 +<h3 id="sec-1-3"><span class="section-number-3">1.3</span> Ex </h3>
  24.257 +<div class="outline-text-3" id="text-1-3">
  24.258 +
  24.259 +<ol>
  24.260 +<li>If \(a\) and \(b\) are nilpotent, then \(ab\) is nilpotent.
  24.261 +</li>
  24.262 +<li>Even if \(a\) and \(b\) are nilpotent, the sum \(a+b\) may not be.
  24.263 +</li>
  24.264 +<li>Even if \(a+b\) is nilpotent, either summand \(a\), \(b\) may not be.
  24.265 +</li>
  24.266 +<li>
  24.267 +</li>
  24.268 +</ol>
  24.269 +
  24.270 +
  24.271 +
  24.272 +</blockquote>
  24.273 +
  24.274 +</div>
  24.275 +</div>
  24.276 +</div>
  24.277 +<div id="postamble">
  24.278 +<p class="date">Date: 2011-08-15 22:42:41 EDT</p>
  24.279 +<p class="author">Author: Dylan Holmes</p>
  24.280 +<p class="creator">Org version 7.6 with Emacs version 23</p>
  24.281 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  24.282 +</div>
  24.283 +</div>
  24.284 +</body>
  24.285 +</html>
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/categorical/synthetic.org	Fri Oct 28 00:03:05 2011 -0700
    25.3 @@ -0,0 +1,68 @@
    25.4 +#+TITLE: Synthetic Differential Geometry
    25.5 +#+author: Dylan Holmes
    25.6 +#+EMAIL:     rlm@mit.edu
    25.7 +#+MATHJAX: align:"left" mathml:t path:"../MathJax/MathJax.js"
    25.8 +#+STYLE: <link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
    25.9 +#+OPTIONS:   H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
   25.10 +#+SETUPFILE: ../templates/level-0.org
   25.11 +#+INCLUDE: ../templates/level-0.org
   25.12 +#+BABEL: :noweb yes :results silent
   25.13 +
   25.14 +(My notes on Anders Kock's /Synthetic Differential Geometry/)
   25.15 +
   25.16 +* Revisiting the real line
   25.17 +
   25.18 +*Lines*, the kind which Euclid talked about, each constitute a commutative
   25.19 + ring: you choose any two points on the line to be 0 and 1, then add
   25.20 + and multiply as if you were dealing with real numbers $\mathbb{R}$.
   25.21 +
   25.22 +Euclid moreover uses the axiom that for any two points, /either/ they are the
   25.23 +same point /or/ there is a unique line between them. Algebraically,
   25.24 +this amounts to saying that each line is not only a commutative ring
   25.25 +but a *field*, as well. This marks our first departure from euclidean
   25.26 +geometry, as our first axiom denies that each line is a field.
   25.27 +
   25.28 +
   25.29 +** The first anti-euclidean axiom
   25.30 +A point in a ring is called *nilpotent* if its square is
   25.31 +zero. Normally (that is, in $\mathbb{R}^n$), only $0$ is
   25.32 +nilpotent. Here, as a consequence of the following axiom, there will
   25.33 +exist other elements that are nilpotent. These elements will
   25.34 +encapsulate our intuitive idea of \ldquo{}infinitesimally small\rdquo{} numbers.
   25.35 +
   25.36 +#+begin_quote
   25.37 +*Axiom 1:* Let $R$ be the line, considered as a commutative ring, and
   25.38 + let $D\subset R$ be the set of nilpotent elements on the line. Then for any
   25.39 + morphism $g:D\rightarrow R$, there exists a unique $b\in R$ such that
   25.40 +
   25.41 +\(\forall d\in D, g(d) = g(0)+ b\cdot d\)
   25.42 +
   25.43 +Intuitively, this unique $b$ is the slope of the function $g$ near
   25.44 +zero. Because every morphism $g$ has exactly one such $b$, we have the
   25.45 +following results:
   25.46 +
   25.47 +1. The set $D$ of nilpotent elements contains more than
   25.48 +   just 0. Indeed, suppose the contrary: if $D=\{0\}$, then for any $g$, /every/ $b\in R$ has the
   25.49 +   property described above;\mdash{}$b$ isn't uniquely defined.
   25.50 +2. Pick $b_1$ and $b_2$ in $R$. If every nilpotent $d$ satisfies $d\cdot
   25.51 +   b_1 = d\cdot b_2$, then $b_1$ and $b_2$ are equal.
   25.52 +
   25.53 +** The first axiom $\ldots$ in terms of arrows
   25.54 +
   25.55 +Define $\xi:R\times R\rightarrow R^D$ by \(\xi:(a,b)\mapsto (d\mapsto
   25.56 +a+b\cdot d)\). The first axiom is equivalent to the statement
   25.57 +\ldquo{}\xi is invertible (i.e., a bijection)\rdquo{}
   25.58 +
   25.59 +We give $R\times R$ the structure of an $R$-algebra by defining
   25.60 +multiplication: \( (a_1,b_1)\star(a_2,b_2) = (a_1\cdot a_2,\quad
   25.61 +a_1\cdot b_2 + a_2\cdot b_1)\). This is called *dual-numbers
   25.62 +multiplication*, and is similar to muliplication of complex numbers.
   25.63 +
   25.64 +
   25.65 +** Ex
   25.66 +1. If $a$ and $b$ are nilpotent, then $ab$ is nilpotent.
   25.67 +2. Even if $a$ and $b$ are nilpotent, the sum $a+b$ may not be.
   25.68 +3. Even if $a+b$ is nilpotent, either summand $a$, $b$ may not be.
   25.69 +4. 
   25.70 + 
   25.71 +#+end_quote
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/chat/room.clj	Fri Oct 28 00:03:05 2011 -0700
    26.3 @@ -0,0 +1,34 @@
    26.4 +(ns chat.room
    26.5 +  (:use [clojure.contrib server-socket duck-streams str-utils])
    26.6 +  (:gen-class))
    26.7 +
    26.8 +
    26.9 +;; CHAT ROOMS
   26.10 +
   26.11 +(def rooms (ref {}))
   26.12 +
   26.13 +(defn get-room! "Returns the chat room with the given name, creating it if necessary." [name]
   26.14 +  (dosync
   26.15 +   (or (@rooms name)
   26.16 +       (let [new-room (agent '())]
   26.17 +	 (do (alter *rooms* assoc name new-room))))))
   26.18 +
   26.19 +(defn say-in-room[room message]
   26.20 +  (doseq [[_ output] room]
   26.21 +    (binding [*out* output]
   26.22 +      (println message))))
   26.23 +
   26.24 +
   26.25 +;; USERS
   26.26 +
   26.27 +(defn user-join[room username output-channel]
   26.28 +  (conj room [username output-channel]))
   26.29 +(defn user-leave[room username]
   26.30 +  (remove #(= (% 0) username) room))
   26.31 +
   26.32 +
   26.33 +(def *username* "Someone")
   26.34 +(defn- join-room [room]
   26.35 +  (send room user-join *username* *out*)
   26.36 +  (send room 
   26.37 +  )
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/clojure_magick/magick.clj	Fri Oct 28 00:03:05 2011 -0700
    27.3 @@ -0,0 +1,151 @@
    27.4 +(ns clojure-magick.magick)
    27.5 +(import [org.im4java.core ConvertCmd IMOperation Stream2BufferedImage] )
    27.6 +
    27.7 +(defn read-image "Read the image in the specified file; returns a BufferedImage." [filename]
    27.8 +  (let [op (doto (IMOperation.)
    27.9 +	     (.addImage (into-array String [filename]))
   27.10 +	     (.addImage (into-array String ["-"])))
   27.11 +	s2b (Stream2BufferedImage.)]
   27.12 +    (doto (ConvertCmd.)
   27.13 +      (.setOutputConsumer s2b)
   27.14 +      (.run op (into-array Object [])))
   27.15 +    (.getImage s2b))
   27.16 +)
   27.17 +
   27.18 +(defn write-image "Write the image to the specified file." [img filename]
   27.19 +  (let [op (doto (IMOperation.)
   27.20 +	     (.addImage)
   27.21 +	     (.addImage))]
   27.22 +    (.run (ConvertCmd.) op  (into-array Object [img filename])))
   27.23 +)
   27.24 +
   27.25 +
   27.26 +(defn glue-vertical "Concatenate images in a sequence from top to bottom, producing a new image." [image & imgs]
   27.27 +  (let [imgs (cons image imgs)
   27.28 +	op (doto (IMOperation.)
   27.29 +	     (.addImage (count imgs))
   27.30 +	     (.append)
   27.31 +	     (.addImage (into-array String ["-"])))
   27.32 +	s2b (Stream2BufferedImage.)]
   27.33 +    (doto (ConvertCmd.)
   27.34 +      (.setOutputConsumer s2b)
   27.35 +      (.run op (into-array Object (vec imgs))))
   27.36 +    (.getImage s2b)
   27.37 +))
   27.38 +
   27.39 +(defn glue-horizontal "Concatenate images in a sequence from left to right, producing a new image." [image & imgs]
   27.40 +  (let [imgs (cons image imgs)
   27.41 +	op (doto (IMOperation.)
   27.42 +	     (.addImage (count imgs))
   27.43 +	     (.p_append)
   27.44 +	     (.addImage (into-array String ["-"])))
   27.45 +	s2b (Stream2BufferedImage.)]
   27.46 +    (doto (ConvertCmd.)
   27.47 +      (.setOutputConsumer s2b)
   27.48 +      (.run op (into-array Object (vec imgs))))
   27.49 +    (.getImage s2b)
   27.50 +  ))
   27.51 +
   27.52 +
   27.53 +
   27.54 +(defn resize "Resize the image, keeping the same aspect ratio."
   27.55 +  ([img width height]
   27.56 +  (let [op (doto (IMOperation.)
   27.57 +	     (.addImage)
   27.58 +	     (.resize width height)
   27.59 +	     (.addImage (into-array String ["-"])))
   27.60 +	s2b (Stream2BufferedImage.)]
   27.61 +    (doto (ConvertCmd.)
   27.62 +      (.setOutputConsumer s2b)
   27.63 +      (.run op (into-array Object [img])))
   27.64 +    (.getImage s2b)
   27.65 +    ))
   27.66 +  (
   27.67 +  [img width]
   27.68 +    (resize img width nil)
   27.69 +  )
   27.70 +)
   27.71 +
   27.72 +
   27.73 +(defn upside-down "Flip the image upside down."
   27.74 +  [img]
   27.75 +  (let [op (doto (IMOperation.)
   27.76 +	     (.addImage)
   27.77 +	     (.flip)
   27.78 +	     (.addImage (into-array String ["-"])))
   27.79 +	s2b (Stream2BufferedImage.)]
   27.80 +    (doto (ConvertCmd.)
   27.81 +      (.setOutputConsumer s2b)
   27.82 +      (.run op (into-array Object [img])))
   27.83 +    (.getImage s2b)
   27.84 +    )
   27.85 +)
   27.86 +
   27.87 +
   27.88 +(defn scale-rotate-translate "Scale the image, then rotate the image about the axis coordinates, then translate the image by the given amount. Does not change the dimensions of the picture."
   27.89 +  ([img axis-x axis-y scale-x scale-y degrees translate-x translate-y]
   27.90 +     (let [arg-str (apply str (list axis-x "," axis-y " " scale-x "," scale-y " " degrees " " translate-x "," translate-y))
   27.91 +	   op (doto (IMOperation.)
   27.92 +		(.addImage)
   27.93 +		(.distort "ScaleRotateTranslate" arg-str)
   27.94 +		(.addImage (into-array String ["-"])))
   27.95 +	   s2b (Stream2BufferedImage.)]
   27.96 +       (doto (ConvertCmd.)
   27.97 +	 (.setOutputConsumer s2b)
   27.98 +	 (.run op (into-array Object [img])))
   27.99 +       (.getImage s2b)))
  27.100 +  ([img axis-x axis-y scale degrees translate-x translate-y]
  27.101 +     (recur axis-x axis-y scale scale degrees translate-x translate-y))
  27.102 +)
  27.103 +     
  27.104 +
  27.105 +(defn rotate "Rotate the image clockwise by the given amount." [img degrees]
  27.106 +  (let [op (doto (IMOperation.)
  27.107 +	     (.addImage)
  27.108 +	     (.distort "ScaleRotateTranslate" (str degrees))
  27.109 +	     (.addImage (into-array String ["-"])))
  27.110 +	s2b (Stream2BufferedImage.)]
  27.111 +    (doto (ConvertCmd.)
  27.112 +      (.setOutputConsumer s2b)
  27.113 +      (.run op (into-array Object [img])))
  27.114 +    (.getImage s2b))
  27.115 +)
  27.116 +
  27.117 +
  27.118 +
  27.119 +
  27.120 +
  27.121 +
  27.122 +
  27.123 +
  27.124 +
  27.125 +
  27.126 +
  27.127 +
  27.128 +
  27.129 +
  27.130 +
  27.131 +
  27.132 +
  27.133 +
  27.134 +
  27.135 +
  27.136 +
  27.137 +
  27.138 +
  27.139 +
  27.140 +
  27.141 +
  27.142 +(defn resize[]
  27.143 +  (let [op (doto (IMOperation.)
  27.144 +	     (.addImage (into-array String ["/home/r/jiggly.gif"]))
  27.145 +	     (.resize 800 600)
  27.146 +	     (.addImage (into-array String ["/home/r/jiggly_sm.gif"]))
  27.147 +	     )]
  27.148 +    (.run (ConvertCmd.) op (into-array Object []))))
  27.149 +
  27.150 +
  27.151 +(defn run-test[]
  27.152 +  (let [puff (read-image "/home/r/jiggly.gif")]
  27.153 +    (write-image (glue-horizontal puff puff puff) "/home/r/multijiggly.gif")
  27.154 +    ))
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/mtg/bk.clj	Fri Oct 28 00:03:05 2011 -0700
    28.3 @@ -0,0 +1,39 @@
    28.4 +(ns mtg.frame)
    28.5 +
    28.6 +;; GENERALLY USEFUL FUNCTIONS
    28.7 +
    28.8 +(defn assay "Takes x and a series of pred-value pairs. Returns a list of vals for which the corresponding preds are true of x." [x & pred-vals]
    28.9 +  (reduce #(if ((first %2) x) (conj %1 (second %2))) '() pred-vals)
   28.10 +  )
   28.11 +(defn alter-val "Applies f to the current value associated with each key, associating each key with the value returned." [m f & keys]
   28.12 +  (map #(assoc m % (f (get m %))) keys))
   28.13 +
   28.14 +(defn every-nth "Returns every nth member of coll. If n is not positive, returns an empty list." [n coll]
   28.15 +  (if (<= n 0) '()
   28.16 +  (take-while (comp not nil?) (map first (iterate #(nthnext % n) coll)))))
   28.17 +
   28.18 +
   28.19 +
   28.20 +
   28.21 +
   28.22 +;; FRAME MANIPULATION
   28.23 +
   28.24 +
   28.25 +(defn conj-key "Adds the xs to the seq associated with the given key." [map key & xs]
   28.26 + (assoc map key (apply conj (get map key []) xs)))
   28.27 +
   28.28 +(defn update "Takes a frame and a sequence of key-fn pairs. Applies f to the current value associated with key, updating the current value with the result.  Frames generate and store a unique id for each call to update."
   28.29 +  [frame & kfs]
   28.30 +  (let [id (gensym "up_")
   28.31 +	keys (every-nth 2 kfs)
   28.32 +	fns (every-nth 2 (rest kfs))]
   28.33 +
   28.34 +    ((reduce comp (map (fn[k f](fn[m](conj-key m k (list id f) )) keys fns))
   28.35 +    (conj-key frame :*bindings* (map (fn [k f](list id k)) keys fns))
   28.36 +    )
   28.37 +))
   28.38 +
   28.39 +
   28.40 +
   28.41 +
   28.42 +(def *frame* (atom {:*bindings* '()}))
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/mtg/continuation.clj	Fri Oct 28 00:03:05 2011 -0700
    29.3 @@ -0,0 +1,159 @@
    29.4 +(ns mtg.continuation)
    29.5 +;; convention: cps function names end in &
    29.6 +
    29.7 +(def not-nil? (comp not nil?))
    29.8 +(defn cpt "Continuation-passing transform. Makes f take a continuation as an additional argument."[f]
    29.9 +  (fn[& args]
   29.10 +    ((last args) (apply f (butlast args)))))
   29.11 +
   29.12 +
   29.13 +
   29.14 +;; Card operations
   29.15 +
   29.16 +
   29.17 +;; Open predicates
   29.18 +					;(defmacro literal-to-keyword[x] `(keyword (quote ~x)))
   29.19 +(defrecord Oracle [])
   29.20 +(def *oracle* (atom (Oracle.)))
   29.21 +
   29.22 +(defn ask* [m k](get @m k (cpt(constantly nil))))
   29.23 +(defn tell!* [m k v] (swap! m assoc k v))
   29.24 +
   29.25 +(def ask(partial ask* *oracle*))
   29.26 +;(def ? (fn [k & args] (apply (ask k) args)))
   29.27 +     
   29.28 +(def tell! (partial tell!* *oracle*))
   29.29 +(defn extend[k f] ((ask k) f))
   29.30 +
   29.31 +;; PRELIMINARY DEFINITIONS
   29.32 +(defmacro defq "Defines a query." [name params & body]
   29.33 +  `(tell! (keyword ~name) (fn ~params ~@body)))
   29.34 +(defmacro ? "Asks a query." [name & args]
   29.35 +  `((ask (keyword name)) ~@args))  
   29.36 +
   29.37 +(defn true-preds "Returns a sequence of the preds for which (pred obj) returns true."
   29.38 +  [obj & preds]
   29.39 +  (map (comp (partial apply str) rest butlast str)
   29.40 +       (filter #(? % obj) preds)))
   29.41 +
   29.42 +(tell! :the-players #{})
   29.43 +(tell! :player? (fn[obj & _] (not-nil? (? the-players obj)))) 
   29.44 +
   29.45 +
   29.46 +
   29.47 +
   29.48 +
   29.49 +
   29.50 +
   29.51 +(defq object? [obj & _] ;; 109.1
   29.52 +  ((comp not empty?)(true-preds obj :card? :copied-card? :token? :spell? :permanent? :emblem?)))
   29.53 +
   29.54 +(defq has-controller? [obj & _]
   29.55 +  (if (and (not (? in-zone 'battlefield obj))
   29.56 +	   (not (? on-stack obj))) false))
   29.57 +
   29.58 +(defq take-turn [player & _] nil)
   29.59 +
   29.60 +
   29.61 +(tell! :characteristics (fn[obj & _]
   29.62 +			  (list :name :mana-cost :color :card-type :subtype :supertype :expansion-symbol :rules-text :abilities :power :toughness :loyalty :hand-modifier :life-modifier)))
   29.63 +
   29.64 +
   29.65 +	      
   29.66 +
   29.67 +(tell! :colors
   29.68 +       (fn[obj & _]
   29.69 +	 (true-preds obj :red? :blue? :green? :white? :black?)))
   29.70 +
   29.71 +
   29.72 +
   29.73 +
   29.74 +
   29.75 +
   29.76 +;; GAME / TURN MECHANICS
   29.77 +(defn new-game "Start a new two-player game."[]
   29.78 +  (tell! :the-players #{'PLAYERONE 'PLAYERTWO})
   29.79 +  (tell! :life-total (reduce #(assoc %1 (keyword %2) 20) {} (ask :the-players) ))
   29.80 +)
   29.81 +
   29.82 +
   29.83 +
   29.84 +;;(ask :blue) blue? = (fn[& args](fn[k] (k  ...) ))
   29.85 +;;            (cpt (constantly nil))
   29.86 +;;(ask k) = (get self k (cpt(constantly nil))) 
   29.87 +
   29.88 +
   29.89 +
   29.90 +
   29.91 +
   29.92 +
   29.93 +(defn reverse&[coll k]
   29.94 +  (if (empty? coll) (k '())
   29.95 +      (recur (rest coll) (fn[x](k (conj x (first coll))))
   29.96 +
   29.97 +      )))
   29.98 +					    
   29.99 +
  29.100 +
  29.101 +
  29.102 +
  29.103 +
  29.104 +
  29.105 +
  29.106 +
  29.107 +
  29.108 +
  29.109 +
  29.110 +
  29.111 +
  29.112 +
  29.113 +
  29.114 +(defn choose "Asks player to choose a member of the universe which matches all the given predicate; returns the chosen member." [player & preds]
  29.115 +  
  29.116 +  )
  29.117 +
  29.118 +
  29.119 +(defn get* "Returns the value of key for the object, default or nil if key is not present." 
  29.120 +  ([obj key])
  29.121 +  ([obj key default]))
  29.122 +
  29.123 +
  29.124 +
  29.125 +
  29.126 +
  29.127 +
  29.128 +
  29.129 +
  29.130 +
  29.131 +
  29.132 +
  29.133 +
  29.134 +
  29.135 +;; shuffle decks
  29.136 +;; anyone may cut anyone else's deck
  29.137 +;; deck => library
  29.138 +;; decide who goes first
  29.139 +;; players decide whether to mulligan in APNAP
  29.140 +;; players mulligan simultaneously
  29.141 +;; ... finish mulligans
  29.142 +;; opening hand abilities
  29.143 +;; beginning game abilities
  29.144 +;; 2P game: first player skips draw phase of first turn
  29.145 +
  29.146 +;; pooled mana: produced-by, spendable-on
  29.147 +
  29.148 +
  29.149 +
  29.150 +
  29.151 +;; VALUES WITH MODIFICATION HISTORY
  29.152 +;(deftype trace[subject ])
  29.153 +
  29.154 +;(defn trace [x]{:subject x :modifiers '()})
  29.155 +;(defn modifiers[tr] (get :modifiers tr '()))
  29.156 +;(defn subject[tr] (:subject tr)) 
  29.157 +
  29.158 +;(defn modify[tr f](assoc tr :modifiers (conj (modifiers tr) f)))
  29.159 +;(defn compute[tr]  (:modifiers tr))
  29.160 +
  29.161 +;; players
  29.162 +
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/mtg/frame.clj	Fri Oct 28 00:03:05 2011 -0700
    30.3 @@ -0,0 +1,50 @@
    30.4 +(ns mtg.frame)
    30.5 +
    30.6 +;; GENERALLY USEFUL FUNCTIONS
    30.7 +
    30.8 +(defn assay "Takes x and a series of pred-value pairs. Returns a list of vals for which the corresponding preds are true of x." [x & pred-vals]
    30.9 +  (reduce #(if ((first %2) x) (conj %1 (second %2))) '() pred-vals)
   30.10 +  )
   30.11 +(defn alter-val "Applies f to the current value associated with each key, associating each key with the value returned." [m f & keys]
   30.12 +  (map #(assoc m % (f (get m %))) keys))
   30.13 +
   30.14 +(defn every-nth "Returns every nth member of coll. If n is not positive, returns an empty list." [n coll]
   30.15 +  (if (<= n 0) '()
   30.16 +  (take-while (comp not nil?) (map first (iterate #(nthnext % n) coll)))))
   30.17 +
   30.18 +
   30.19 +
   30.20 +
   30.21 +
   30.22 +;; FRAME MANIPULATION
   30.23 +
   30.24 +(defn conj-key "Adds the xs to the seq associated with the given key." [map key & xs]
   30.25 + (assoc map key (apply conj (get map key []) xs)))
   30.26 +
   30.27 +(defn update "Takes a frame and a sequence of key-fn pairs. Applies f to the current value associated with key, updating the current value with the result.  Frames generate and store a unique id for each call to update."
   30.28 +  [frame & kfs]
   30.29 +  (let [id (gensym "")
   30.30 +	keys (every-nth 2 kfs)
   30.31 +	fns (every-nth 2 (rest kfs))]
   30.32 +
   30.33 +    ((reduce comp (map (fn[k f](fn[m](conj-key m k (list id f)))) keys fns))
   30.34 +    (conj-key frame :*bindings* (map (fn [k f](list id k)) keys fns))
   30.35 +    )
   30.36 +))
   30.37 +
   30.38 +(defn rollback "Undo the update with the given id." [frame id]
   30.39 +  (let [affected-keys
   30.40 +	(conj (map second (filter #(=(first %) id) (:*bindings* frame))) :*bindings*)]
   30.41 +    (reduce (fn[frame key]
   30.42 +	      (alter-val (partial filter #(=(first %) id)) key)
   30.43 +	      ) frame affected-keys)
   30.44 +  ))
   30.45 +
   30.46 +
   30.47 +(defn get-fn "Keys in a frame store lists of modifiers. Produces the end result of applying all the modifiers in order." [frame key]
   30.48 +    (reduce #(%2) (constantly nil) (list (constantly 1)))
   30.49 +)
   30.50 +
   30.51 +
   30.52 +(def *frame* (atom {:*bindings* '()}))
   30.53 + 
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/mtg/mtg_cards.txt	Fri Oct 28 00:03:05 2011 -0700
    31.3 @@ -0,0 +1,42 @@
    31.4 +:name	"Mountain"
    31.5 +:color	'R
    31.6 +:type	"Land"
    31.7 +:supertype "Basic"
    31.8 +:subtype   "Mountain"
    31.9 +:rarity	   'C
   31.10 +	
   31.11 +:name	"Island"
   31.12 +:color	'B
   31.13 +:type	"Land"
   31.14 +:supertype "Basic"
   31.15 +:subtype   "Island"
   31.16 +:rarity	   'C
   31.17 +
   31.18 +:name	"Forest"
   31.19 +:color	'G
   31.20 +:type	"Land"
   31.21 +:supertype "Basic"
   31.22 +:subtype   "Forest"
   31.23 +:rarity	   'C
   31.24 +
   31.25 +:name	"Plains"
   31.26 +:color	'W
   31.27 +:type	"Land"
   31.28 +:supertype "Basic"
   31.29 +:subtype   "Plains"
   31.30 +:rarity	   'C
   31.31 +
   31.32 +:name	"Swamp"
   31.33 +:color	'B
   31.34 +:type	"Land"
   31.35 +:supertype "Basic"
   31.36 +:subtype   "Swamp"
   31.37 +:rarity	   'C
   31.38 +
   31.39 +:name "Knight Errant"
   31.40 +:color	      'W
   31.41 +:cost	      "1W"
   31.42 +:type	      "Creature"
   31.43 +:subtype      "Human Knight"
   31.44 +:p	      2
   31.45 +:t	      2
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/org/science.org	Fri Oct 28 00:03:05 2011 -0700
    32.3 @@ -0,0 +1,44 @@
    32.4 +#+title: Science Minus Science 
    32.5 +#+author: Dylan Holmes
    32.6 +#+email: ocsenave@gmail.com
    32.7 +#+description: What's wrong with our current Science Education?
    32.8 +#+SETUPFILE: ../../aurellem/org/setup.org
    32.9 +#+INCLUDE: ../../aurellem/org/level-0.org
   32.10 +
   32.11 +
   32.12 +From what I've seen, today's science classrooms are remarkably
   32.13 +unscientific. Someone has decided that it is less important to teach
   32.14 +the empirical mindset than to impart our accumulated scientific
   32.15 +knowledge. Thus, because the field is so vast nowadays, teachers are
   32.16 +obliged to be frugal with the facts: they must prune tangential
   32.17 +subjects and pare whatever's left, watering down complicated results
   32.18 +into simplified half-truths. Needs must when the devil drives, of
   32.19 +course--but what is the end result?
   32.20 +
   32.21 +In modern science classrooms, we force-feed students a deluge of
   32.22 +unfamiliar scientific dogma which they must swallow in time to
   32.23 +regurgitate onto an exam. To accomplish this daunting task, they
   32.24 +cannot possibly stop to consider various alternatives which scientists
   32.25 +have methodically eliminated over the course of centuries; instead,
   32.26 +they must simply trust that science has done what it purports to have
   32.27 +done--or, faster, simply stamp out their conjectural, critical
   32.28 +instincts.
   32.29 +
   32.30 +By the end of such a course, students might be able to recite the
   32.31 +tenets of our current scientific creed and might employ those tenets
   32.32 +when answering carefully formulated questions. But even if, by chance,
   32.33 +our students get their facts straight, they will have acquired at most
   32.34 +only our pre-processed truths, and nothing of the empirical machinery
   32.35 +that produced them. In my opinion, such a lackluster result demands
   32.36 +that we re-evaluate our priorities. Surely the shibboleth of the
   32.37 +scientist is not his ability to recount the bleeding-edge depiction of
   32.38 +reality--after all, theories are transient and revolutions expected--but
   32.39 +rather his pervasive inquiries about the world and his methodical,
   32.40 +empirical approach to answering them? Indeed, don't we recognize the
   32.41 +scientist by his lack of allegiance to the status quo, by the way he
   32.42 +scrutinizes even his own theories with utmost irreverence?
   32.43 +
   32.44 +In valuing data absorption over methodical reason, we give our
   32.45 +students a fragmentary and moreover inexplicable impression of
   32.46 +reality. We must ask ourselves: how much of science is left in that?
   32.47 +
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/proof.org	Fri Oct 28 00:03:05 2011 -0700
    33.3 @@ -0,0 +1,151 @@
    33.4 +#+TITLE: WFF 'n Proof
    33.5 +#+AUTHOR: Dylan Holmes
    33.6 +#+MATHJAX: align:"left" mathml:t path:"../MathJax/MathJax.js"
    33.7 +#+STYLE: <link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
    33.8 +#+OPTIONS:   H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
    33.9 +#+SETUPFILE: ../templates/level-0.org
   33.10 +#+INCLUDE: ../templates/level-0.org
   33.11 +#+BABEL: :noweb yes :results verbatim :cache yes
   33.12 +
   33.13 +
   33.14 +* Introduction
   33.15 +WFF 'n Proof is a competitive dice game designed to teach logic. The
   33.16 +game is played with several dice whose faces are marked with logical
   33.17 +symbols; the goal is to arrange the dice into /well-formed formulas/ (WFFs) \mdash{}
   33.18 +expressions that are syntactically correct\mdash{}then to manipulate
   33.19 +these formulas to form valid proofs.
   33.20 +
   33.21 +** About the dice
   33.22 +WFF and Proof has small cubes and large cubes which you use like
   33.23 +dice. The small cubes have lower-case letters =p=, =q=, =r=, =s=, =i=,
   33.24 +and =o= inscribed on their faces, whereas the big cubes have
   33.25 +upper-case letters =C=, =A=, =K=, =E=, =N= and =R= on their faces. The
   33.26 +lower-case letters stand for /propositions/ that can be either true or
   33.27 +false, whereas the
   33.28 +upper-case letters stand for certain logical connectives:
   33.29 +
   33.30 +
   33.31 +| Symbol | Meaning |
   33.32 +|--------+---------|
   33.33 +| =C=    | Implies |
   33.34 +| =A=    | Or      |
   33.35 +| =K=    | And     |
   33.36 +| =E=    | Equals  |
   33.37 +|--------+---------|
   33.38 +| =N=    | Not     |
   33.39 +
   33.40 +** Well-formed formulas
   33.41 +An expression is a row of dice arranged left-to-right. An expression
   33.42 +is a well-formed formula (WFF) if and only if
   33.43 +- It is a =p=, =q=, =r=, or =s=; or
   33.44 +- It is an =N= followed by a WFF; or
   33.45 +- It is a =C=, =A=, =K=, or =E= followed by two WFFs.
   33.46 +
   33.47 +(Both the lower-case letters =i= and =o= and the upper-case letter =R=
   33.48 +are special, and are not used in forming WFFs)
   33.49 +
   33.50 +* Games you can play with WFF 'n Proof
   33.51 +** Shake a WFF
   33.52 +Shake a WFF is the simplest game; it teaches you to build and to
   33.53 +recognize well-formed formulas, skills that are fundamental to more advanced games. 
   33.54 +
   33.55 +#This game is for two or three players. 
   33.56 +Each player starts the game with two small cubes and one big cube;
   33.57 +these cubes constitute each player's hand. Divide the remaining cubes
   33.58 +evenly among the players so that each player has a pile of unused
   33.59 +cubes. Also allow space for completed WFFs.
   33.60 +
   33.61 +At the start of each turn, all of the players toss their dice
   33.62 +simultaneously; each player races to build the longest WFF possible
   33.63 +out of his own dice. As soon as a player is finished\mdash{}either he
   33.64 +has constructed the longest WFF possible or has found that it is impossible to make a WFF\mdash{}he
   33.65 +calls out \ldquo{}WFF!\rdquo{} or \ldquo{}No WFF!\rdquo{}. 
   33.66 +
   33.67 +When a player calls out \ldquo{}WFF!\rdquo{} or \ldquo{}No
   33.68 +WFF!\rdquo{}, the other players must stop to validate the caller's
   33.69 +claim. When a player confirms that the claim is correct, that player
   33.70 +calls out \ldquo{}Check!\rdquo{}. Now, either all the players believe
   33.71 +that the claim is correct, or they do not.
   33.72 +
   33.73 +
   33.74 +- If all the players confirm that the claim is correct, the caller
   33.75 +  puts his WFF in the area for completed WFFs, then replenishes his
   33.76 +  supply of cubes by replacing each of the cubes in his WFF with a
   33.77 +  cube from his unused-cubes pile (each big cube must be replaced with
   33.78 +  a big cube, and each small cube must be replaced with a small cube),
   33.79 +  then takes an additional cube from his pile and receives one
   33.80 +  point. The turn then ends.
   33.81 +
   33.82 +- If, when checking the caller's claim, a player believes that the
   33.83 +  claim was made in error, the player calls out
   33.84 +  \ldquo{}Challenge!\rdquo{}, then points out the mistake: 
   33.85 +  - If the caller has presented an expression that is not a WFF, the
   33.86 +    challenger shows that it is not a WFF.
   33.87 +  - If the caller has presented a WFF that is not the longest possible,
   33.88 +    the challenger shows how to make a longer WFF from the caller's
   33.89 +    cubes.
   33.90 +  - If it is possible to make a WFF from the caller's cubes but the
   33.91 +    caller claims it is impossible, the challenger shows how to make a
   33.92 +    WFF from the caller's cubes.
   33.93 +  The other players verify this challenge. If the challenge was made
   33.94 +  correctly, the challenging player wins a point and gains an extra
   33.95 +  cube from his pile whereas the calling player must return a cube to his
   33.96 +  pile. If the challenge was made wrongly, the challenger must return a
   33.97 +  cube to his pile. In either case, the turn ends.
   33.98 +
   33.99 +After the turn ends, the player can play another turn. The game ends
  33.100 +when a certain number of cubes are in the area for completed WFFs;
  33.101 +this number can be decided before the game begins.
  33.102 +
  33.103 +One final note is the rule for cubes:
  33.104 +#+begin_quote
  33.105 +*Cube Rule:* A player's hand must have either the same number of big
  33.106 + cubes and small cubes, or one more small cube than big cube. When
  33.107 + taking cubes from or returning cubes to your unusued cubes pile, you
  33.108 + must make sure to follow this rule.
  33.109 +#+end_quote
  33.110 +
  33.111 +
  33.112 +
  33.113 +
  33.114 +
  33.115 +
  33.116 +* Misc
  33.117 +
  33.118 +#+srcname: proof
  33.119 +#+begin_src clojure
  33.120 +(ns wff.proof)
  33.121 +
  33.122 +(defn arity[x]
  33.123 +  (first
  33.124 +   (keep-indexed
  33.125 +    (fn[i f](if (nil? (f x)) nil i))
  33.126 +    [#{'p 'q 'r 's}
  33.127 +     #{'N}
  33.128 +     #{'C 'A 'K 'E}])))
  33.129 +
  33.130 +(defn wff?
  33.131 +  [& symbols]
  33.132 +  ((fn[stack symbols]
  33.133 +     ;;(println stack symbols)
  33.134 +     (if (or(empty? symbols)(empty? stack))
  33.135 +       (and(empty? symbols)(empty? stack))
  33.136 +       (let [n (arity (first symbols))]
  33.137 +	 (if (nil? n)
  33.138 +	   false
  33.139 +	   (recur (concat (rest stack) (repeat n '*)) (rest symbols))))))
  33.140 +   '(*) symbols))
  33.141 +
  33.142 +#+end_src
  33.143 +
  33.144 +
  33.145 +
  33.146 +
  33.147 +
  33.148 +
  33.149 +* COMMENT tangle
  33.150 +
  33.151 +#+begin_src clojure :tangle ./proof.clj
  33.152 +<<proof>>
  33.153 +<<other-proof>>
  33.154 +#+end_src
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/sicm/bk/utils.clj	Fri Oct 28 00:03:05 2011 -0700
    34.3 @@ -0,0 +1,196 @@
    34.4 +
    34.5 +(ns sicm.utils)
    34.6 +
    34.7 +					;***** GENERIC ARITHMETIC
    34.8 +(ns sicm.utils)
    34.9 +(in-ns 'sicm.utils)
   34.10 +
   34.11 +(defprotocol Arithmetic
   34.12 +  (zero [this])
   34.13 +  (one [this]))
   34.14 +
   34.15 +
   34.16 +(extend-protocol Arithmetic
   34.17 +  java.lang.Number
   34.18 +  (zero [this] 0)
   34.19 +  (one [this] 1))
   34.20 +
   34.21 +(extend-protocol Arithmetic
   34.22 +  clojure.lang.Seqable
   34.23 +  (zero [this] (map zero this))
   34.24 +  (one [this] (map one this)))
   34.25 +
   34.26 +
   34.27 +					;***** TUPLES AND MATRICES
   34.28 +(in-ns 'sicm.utils)
   34.29 +
   34.30 +(defprotocol Spinning
   34.31 +  (up? [this])
   34.32 +  (down? [this]))
   34.33 +
   34.34 +(defn spin
   34.35 +  "Returns the spin of the Spinning s, either :up or :down"
   34.36 +  [#^Spinning s]
   34.37 +  (cond (up? s) :up (down? s) :down))
   34.38 +
   34.39 +
   34.40 +(deftype Tuple
   34.41 +  [spin coll]
   34.42 +  clojure.lang.Seqable
   34.43 +  (seq [this] (seq (.coll this)))
   34.44 +  clojure.lang.Counted
   34.45 +  (count [this] (count (.coll this))))
   34.46 +
   34.47 +(extend-type Tuple
   34.48 +  Spinning
   34.49 +  (up? [this] (= ::up (.spin this)))
   34.50 +  (down? [this] (= ::down (.spin this))))
   34.51 +
   34.52 +(defmethod print-method Tuple
   34.53 +  [o w]
   34.54 +  (print-simple (str (if (up? o) 'u 'd) (.coll o))  w))
   34.55 +
   34.56 +
   34.57 +
   34.58 +(defn up
   34.59 +  "Create a new up-tuple containing the contents of coll."
   34.60 +  [coll]
   34.61 +  (Tuple. ::up coll))       
   34.62 +
   34.63 +(defn down
   34.64 +  "Create a new down-tuple containing the contents of coll."
   34.65 +  [coll]
   34.66 +  (Tuple. ::down coll))
   34.67 +
   34.68 +
   34.69 +(in-ns 'sicm.utils)
   34.70 +
   34.71 +(defn numbers?
   34.72 +  "Returns true if all arguments are numbers, else false."
   34.73 +  [& xs]
   34.74 +  (every? number? xs))
   34.75 +
   34.76 +(defn contractible?
   34.77 +  "Returns true if the tuples a and b are compatible for contraction,
   34.78 +  else false. Tuples are compatible if they have the same number of
   34.79 +  components, they have opposite spins, and their elements are
   34.80 +  pairwise-compatible."
   34.81 +  [a b]
   34.82 +  (and
   34.83 +   (isa? (type a) Tuple)
   34.84 +   (isa? (type b) Tuple)
   34.85 +   (= (count a) (count b))
   34.86 +   (not= (spin a) (spin b))
   34.87 +   
   34.88 +   (not-any? false?
   34.89 +	     (map #(or
   34.90 +		    (numbers? %1 %2)
   34.91 +		    (contractible? %1 %2))
   34.92 +		  a b))))
   34.93 +
   34.94 +
   34.95 +
   34.96 +(defn contract
   34.97 +  "Contracts two tuples, returning the sum of the
   34.98 +  products of the corresponding items. Contraction is recursive on
   34.99 +  nested tuples."
  34.100 +  [a b]
  34.101 +  (if (not (contractible? a b))
  34.102 +    (throw
  34.103 +     (Exception. "Not compatible for contraction."))
  34.104 +    (reduce +
  34.105 +	    (map
  34.106 +	     (fn [x y]
  34.107 +	       (if (numbers? x y)
  34.108 +		 (* x y)
  34.109 +		 (contract x y)))
  34.110 +	     a b))))
  34.111 +
  34.112 +					;***** MATRICES
  34.113 +(in-ns 'sicm.utils)
  34.114 +(require 'incanter.core) ;; use incanter's fast matrices
  34.115 +
  34.116 +(defprotocol Matrix
  34.117 +  (rows [this])
  34.118 +  (cols [this])
  34.119 +  (diagonal [this])
  34.120 +  (trace [this])
  34.121 +  (determinant [this]))
  34.122 +
  34.123 +(extend-protocol Matrix
  34.124 +  incanter.Matrix
  34.125 +  (rows [this] (map down this)))
  34.126 +
  34.127 +
  34.128 +
  34.129 +
  34.130 +(defn count-rows [matrix]
  34.131 +  ((comp count rows) matrix))
  34.132 +
  34.133 +(defn count-cols [matrix]
  34.134 +  ((comp count cols) matrix))
  34.135 +
  34.136 +
  34.137 +(defn matrix-by-rows
  34.138 +  "Define a matrix by giving its rows."
  34.139 +  [& rows]
  34.140 +  (cond
  34.141 +   (not (all-equal? (map count rows)))
  34.142 +   (throw (Exception. "All rows in a matrix must have the same number of elements."))
  34.143 +   :else
  34.144 +   (reify Matrix
  34.145 +	  (rows [this] (map down rows))
  34.146 +	  (cols [this] (map up (apply map vector rows)))
  34.147 +	  (diagonal [this] (map-indexed (fn [i row] (nth row i) rows)))
  34.148 +	  (trace [this]
  34.149 +		 (if (not= (count-rows this) (count-cols this))
  34.150 +		   (throw (Exception.
  34.151 +			   "Cannot take the trace of a non-square matrix."))
  34.152 +		   (reduce + (diagonal this))))
  34.153 +	  
  34.154 +	  (determinant [this]
  34.155 +		       (if (not= (count-rows this) (count-cols this))
  34.156 +			 (throw (Exception.
  34.157 +				 "Cannot take the determinant of a non-square matrix."))
  34.158 +			 (reduce * (diagonal this))))
  34.159 +   )))
  34.160 +
  34.161 +
  34.162 +(defn matrix-by-cols
  34.163 +  "Define a matrix by giving its columns."
  34.164 +  [& cols]
  34.165 +  (cond
  34.166 +   (not (all-equal? (map count cols)))
  34.167 +   (throw (Exception. "All columns in a matrix must have the same number of elements."))
  34.168 +   :else
  34.169 +   (reify Matrix
  34.170 +	  (cols [this] (map up cols))
  34.171 +	  (rows [this] (map down (apply map vector cols)))
  34.172 +	  (diagonal [this] (map-indexed (fn [i col] (nth col i) cols)))
  34.173 +	  (trace [this]
  34.174 +		 (if (not= (count-cols this) (count-rows this))
  34.175 +		   (throw (Exception.
  34.176 +			   "Cannot take the trace of a non-square matrix."))
  34.177 +		   (reduce + (diagonal this))))
  34.178 +	  
  34.179 +	  (determinant [this]
  34.180 +		       (if (not= (count-cols this) (count-rows this))
  34.181 +			 (throw (Exception.
  34.182 +				 "Cannot take the determinant of a non-square matrix."))
  34.183 +			 (reduce * (map-indexed (fn [i col] (nth col i)) cols))))
  34.184 +	  )))
  34.185 +
  34.186 +(extend-protocol Matrix Tuple
  34.187 +		 (rows [this] (if (down? this)
  34.188 +				(list this)
  34.189 +				(map (comp up vector) this)))
  34.190 +
  34.191 +		 (cols [this] (if (up? this)
  34.192 +				(list this)
  34.193 +				(map (comp down vector) this))))
  34.194 +
  34.195 +(defn matrix-multiply [A B]
  34.196 +  (apply matrix-by-rows
  34.197 +	 (for [a (rows A)]
  34.198 +	   (for [b (cols B)]
  34.199 +	     (contract a b)))))
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/sicm/bk/utils.html	Fri Oct 28 00:03:05 2011 -0700
    35.3 @@ -0,0 +1,1482 @@
    35.4 +<?xml version="1.0" encoding="utf-8"?>
    35.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    35.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    35.7 +<html xmlns="http://www.w3.org/1999/xhtml"
    35.8 +lang="en" xml:lang="en">
    35.9 +<head>
   35.10 +<title>Building a Classical Mechanics Library in Clojure</title>
   35.11 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
   35.12 +<meta name="generator" content="Org-mode"/>
   35.13 +<meta name="generated" content="2011-08-09 18:41:37 EDT"/>
   35.14 +<meta name="author" content="Robert McIntyre & Dylan Holmes"/>
   35.15 +<meta name="description" content=""/>
   35.16 +<meta name="keywords" content=""/>
   35.17 +<style type="text/css">
   35.18 + <!--/*--><![CDATA[/*><!--*/
   35.19 +  html { font-family: Times, serif; font-size: 12pt; }
   35.20 +  .title  { text-align: center; }
   35.21 +  .todo   { color: red; }
   35.22 +  .done   { color: green; }
   35.23 +  .tag    { background-color: #add8e6; font-weight:normal }
   35.24 +  .target { }
   35.25 +  .timestamp { color: #bebebe; }
   35.26 +  .timestamp-kwd { color: #5f9ea0; }
   35.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
   35.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
   35.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
   35.30 +  p.verse { margin-left: 3% }
   35.31 +  pre {
   35.32 +	border: 1pt solid #AEBDCC;
   35.33 +	background-color: #F3F5F7;
   35.34 +	padding: 5pt;
   35.35 +	font-family: courier, monospace;
   35.36 +        font-size: 90%;
   35.37 +        overflow:auto;
   35.38 +  }
   35.39 +  table { border-collapse: collapse; }
   35.40 +  td, th { vertical-align: top;  }
   35.41 +  th.right  { text-align:center;  }
   35.42 +  th.left   { text-align:center;   }
   35.43 +  th.center { text-align:center; }
   35.44 +  td.right  { text-align:right;  }
   35.45 +  td.left   { text-align:left;   }
   35.46 +  td.center { text-align:center; }
   35.47 +  dt { font-weight: bold; }
   35.48 +  div.figure { padding: 0.5em; }
   35.49 +  div.figure p { text-align: center; }
   35.50 +  textarea { overflow-x: auto; }
   35.51 +  .linenr { font-size:smaller }
   35.52 +  .code-highlighted {background-color:#ffff00;}
   35.53 +  .org-info-js_info-navigation { border-style:none; }
   35.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
   35.55 +                               white-space:nowrap; }
   35.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
   35.57 +                                 font-weight:bold; }
   35.58 +  /*]]>*/-->
   35.59 +</style>
   35.60 +<link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
   35.61 +<script type="text/javascript">
   35.62 +<!--/*--><![CDATA[/*><!--*/
   35.63 + function CodeHighlightOn(elem, id)
   35.64 + {
   35.65 +   var target = document.getElementById(id);
   35.66 +   if(null != target) {
   35.67 +     elem.cacheClassElem = elem.className;
   35.68 +     elem.cacheClassTarget = target.className;
   35.69 +     target.className = "code-highlighted";
   35.70 +     elem.className   = "code-highlighted";
   35.71 +   }
   35.72 + }
   35.73 + function CodeHighlightOff(elem, id)
   35.74 + {
   35.75 +   var target = document.getElementById(id);
   35.76 +   if(elem.cacheClassElem)
   35.77 +     elem.className = elem.cacheClassElem;
   35.78 +   if(elem.cacheClassTarget)
   35.79 +     target.className = elem.cacheClassTarget;
   35.80 + }
   35.81 +/*]]>*///-->
   35.82 +</script>
   35.83 +<script type="text/javascript" src="../MathJax/MathJax.js">
   35.84 +<!--/*--><![CDATA[/*><!--*/
   35.85 +    MathJax.Hub.Config({
   35.86 +        // Only one of the two following lines, depending on user settings
   35.87 +        // First allows browser-native MathML display, second forces HTML/CSS
   35.88 +            config: ["MMLorHTML.js"], jax: ["input/TeX"],
   35.89 +        //  jax: ["input/TeX", "output/HTML-CSS"],
   35.90 +        extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js",
   35.91 +                     "TeX/noUndefined.js"],
   35.92 +        tex2jax: {
   35.93 +            inlineMath: [ ["\\(","\\)"] ],
   35.94 +            displayMath: [ ['$$','$$'], ["\\[","\\]"], ["\\begin{displaymath}","\\end{displaymath}"] ],
   35.95 +            skipTags: ["script","noscript","style","textarea","pre","code"],
   35.96 +            ignoreClass: "tex2jax_ignore",
   35.97 +            processEscapes: false,
   35.98 +            processEnvironments: true,
   35.99 +            preview: "TeX"
  35.100 +        },
  35.101 +        showProcessingMessages: true,
  35.102 +        displayAlign: "left",
  35.103 +        displayIndent: "2em",
  35.104 +
  35.105 +        "HTML-CSS": {
  35.106 +             scale: 100,
  35.107 +             availableFonts: ["STIX","TeX"],
  35.108 +             preferredFont: "TeX",
  35.109 +             webFont: "TeX",
  35.110 +             imageFont: "TeX",
  35.111 +             showMathMenu: true,
  35.112 +        },
  35.113 +        MMLorHTML: {
  35.114 +             prefer: {
  35.115 +                 MSIE:    "MML",
  35.116 +                 Firefox: "MML",
  35.117 +                 Opera:   "HTML",
  35.118 +                 other:   "HTML"
  35.119 +             }
  35.120 +        }
  35.121 +    });
  35.122 +/*]]>*///-->
  35.123 +</script>
  35.124 +</head>
  35.125 +<body>
  35.126 +
  35.127 +<div id="content">
  35.128 +
  35.129 +
  35.130 +
  35.131 +<div class="header">
  35.132 +  <div class="float-right">	
  35.133 +    <!-- 
  35.134 +    <form>
  35.135 +      <input type="text"/><input type="submit" value="search the blog &raquo;"/> 
  35.136 +    </form>
  35.137 +    -->
  35.138 +  </div>
  35.139 +
  35.140 +  <h1>aurellem <em>&#x2609;</em></h1>
  35.141 +  <ul class="nav">
  35.142 +    <li><a href="/">read the blog &raquo;</a></li>
  35.143 +    <!-- li><a href="#">learn about us &raquo;</a></li-->
  35.144 +  </ul>
  35.145 +</div>
  35.146 +
  35.147 +<h1 class="title">Building a Classical Mechanics Library in Clojure</h1>
  35.148 +
  35.149 +
  35.150 +
  35.151 +
  35.152 +
  35.153 +
  35.154 +
  35.155 +<div id="table-of-contents">
  35.156 +<h2>Table of Contents</h2>
  35.157 +<div id="text-table-of-contents">
  35.158 +<ul>
  35.159 +<li><a href="#sec-1">1 Generic Arithmetic </a></li>
  35.160 +<li><a href="#sec-2">2 Useful Data Types </a>
  35.161 +<ul>
  35.162 +<li><a href="#sec-2-1">2.1 Complex Numbers </a></li>
  35.163 +<li><a href="#sec-2-2">2.2 Tuples and Tensors </a>
  35.164 +<ul>
  35.165 +<li><a href="#sec-2-2-1">2.2.1 Contraction </a></li>
  35.166 +<li><a href="#sec-2-2-2">2.2.2 Matrices </a></li>
  35.167 +</ul>
  35.168 +</li>
  35.169 +<li><a href="#sec-2-3">2.3 Power Series </a></li>
  35.170 +</ul>
  35.171 +</li>
  35.172 +<li><a href="#sec-3">3 Basic Utilities </a>
  35.173 +<ul>
  35.174 +<li><a href="#sec-3-1">3.1 Sequence manipulation </a></li>
  35.175 +<li><a href="#sec-3-2">3.2 Ranges, Airity and Function Composition </a></li>
  35.176 +</ul>
  35.177 +</li>
  35.178 +<li><a href="#sec-4">4 Numerical Methods </a></li>
  35.179 +<li><a href="#sec-5">5 Differentiation </a></li>
  35.180 +<li><a href="#sec-6">6 Symbolic Manipulation </a></li>
  35.181 +</ul>
  35.182 +</div>
  35.183 +</div>
  35.184 +
  35.185 +<div id="outline-container-1" class="outline-2">
  35.186 +<h2 id="sec-1"><span class="section-number-2">1</span> Generic Arithmetic </h2>
  35.187 +<div class="outline-text-2" id="text-1">
  35.188 +
  35.189 +
  35.190 +
  35.191 +
  35.192 +
  35.193 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">ns</span> sicm.utils)
  35.194 +(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  35.195 +
  35.196 +
  35.197 +
  35.198 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">all-equal?</span> [coll]
  35.199 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">empty?</span> (<span style="color: #8cd0d3;">rest</span> coll)) true
  35.200 +      (<span style="color: #f0dfaf; font-weight: bold;">and</span> (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">first</span> coll) (<span style="color: #8cd0d3;">second</span> coll))
  35.201 +           (<span style="color: #f0dfaf; font-weight: bold;">recur</span> (<span style="color: #8cd0d3;">rest</span> coll)))))
  35.202 +
  35.203 +
  35.204 +(<span style="color: #f0dfaf; font-weight: bold;">defprotocol</span> <span style="color: #f0dfaf;">Arithmetic</span>
  35.205 +  (zero [this])
  35.206 +  (one [this])
  35.207 +  (negate [this])
  35.208 +  (invert [this])
  35.209 +  (conjugate [this]))
  35.210 +
  35.211 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">zero?</span> [x]
  35.212 +  (<span style="color: #8cd0d3;">=</span> x (zero x)))
  35.213 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">one?</span> [x]
  35.214 +  (<span style="color: #8cd0d3;">=</span> x (one x)))
  35.215 +
  35.216 +
  35.217 +
  35.218 +(<span style="color: #8cd0d3;">extend-protocol</span> Arithmetic
  35.219 +  java.lang.Number
  35.220 +  (zero [x] 0)
  35.221 +  (one [x] 1)
  35.222 +  (negate [x] (<span style="color: #8cd0d3;">-</span> x))
  35.223 +  (invert [x] (<span style="color: #8cd0d3;">/</span> x))
  35.224 +  )
  35.225 +
  35.226 +(<span style="color: #8cd0d3;">extend-protocol</span> Arithmetic
  35.227 +  clojure.lang.IFn
  35.228 +  (one [f] identity)
  35.229 +  (negate [f] (<span style="color: #8cd0d3;">comp</span> negate f))
  35.230 +  (invert [f] (<span style="color: #8cd0d3;">comp</span> invert f)))
  35.231 +
  35.232 +    
  35.233 +(<span style="color: #8cd0d3;">extend-protocol</span> Arithmetic
  35.234 +  clojure.lang.Seqable
  35.235 +  (zero [this] (<span style="color: #8cd0d3;">map</span> zero this))
  35.236 +  (one [this] (<span style="color: #8cd0d3;">map</span> one this))
  35.237 +  (invert [this] (<span style="color: #8cd0d3;">map</span> invert this))
  35.238 +  (negate [this] (<span style="color: #8cd0d3;">map</span> negate this)))
  35.239 +
  35.240 +
  35.241 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">ordered-like</span>
  35.242 +  <span style="color: #8fb28f;">"Create a comparator using the sorted collection as an</span>
  35.243 +<span style="color: #8fb28f;">  example. Elements not in the sorted collection are sorted to the</span>
  35.244 +<span style="color: #8fb28f;">  end."</span>
  35.245 +  [sorted-coll]
  35.246 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [
  35.247 +        sorted-coll? (<span style="color: #8cd0d3;">set</span> sorted-coll) 
  35.248 +        ascending-pair?
  35.249 +        (<span style="color: #8cd0d3;">set</span>(<span style="color: #8cd0d3;">reduce</span> concat
  35.250 +                    (map-indexed
  35.251 +                     (<span style="color: #8cd0d3;">fn</span> [n x]
  35.252 +                       (<span style="color: #8cd0d3;">map</span> #(<span style="color: #8cd0d3;">vector</span> x %) (<span style="color: #8cd0d3;">nthnext</span> sorted-coll n)))
  35.253 +                     sorted-coll)))]
  35.254 +    (<span style="color: #8cd0d3;">fn</span> [x y]
  35.255 +      (<span style="color: #f0dfaf; font-weight: bold;">cond</span>
  35.256 +       (<span style="color: #8cd0d3;">=</span> x y) 0
  35.257 +       (ascending-pair? [x y]) -1
  35.258 +       (ascending-pair? [y x]) 1
  35.259 +       (sorted-coll? x) -1
  35.260 +       (sorted-coll? y) 1))))
  35.261 +  
  35.262 +
  35.263 +
  35.264 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">type-precedence</span>
  35.265 +  (ordered-like [incanter.Matrix]))
  35.266 +
  35.267 +(<span style="color: #f0dfaf; font-weight: bold;">defmulti</span> <span style="color: #f0dfaf;">add</span>
  35.268 +    (<span style="color: #8cd0d3;">fn</span> [x y]
  35.269 +      (<span style="color: #8cd0d3;">sort</span> type-precedence [(<span style="color: #8cd0d3;">type</span> x)(<span style="color: #8cd0d3;">type</span> y)]))) 
  35.270 +
  35.271 +(<span style="color: #f0dfaf; font-weight: bold;">defmulti</span> <span style="color: #f0dfaf;">multiply</span>
  35.272 +  (<span style="color: #8cd0d3;">fn</span> [x y]
  35.273 +    (<span style="color: #8cd0d3;">sort</span> type-precedence [(<span style="color: #8cd0d3;">type</span> x) (<span style="color: #8cd0d3;">type</span> y)])))
  35.274 +
  35.275 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">add</span> [java.lang.Number java.lang.Number] [x y] (<span style="color: #8cd0d3;">+</span> x y))
  35.276 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">multiply</span> [java.lang.Number java.lang.Number] [x y] (<span style="color: #8cd0d3;">*</span> x y))
  35.277 +
  35.278 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">multiply</span> [incanter.Matrix java.lang.Integer] [x y]
  35.279 +           (<span style="color: #f0dfaf; font-weight: bold;">let</span> [args (<span style="color: #8cd0d3;">sort</span> #(type-precedence (<span style="color: #8cd0d3;">type</span> %1)(<span style="color: #8cd0d3;">type</span> %2)) [x y])
  35.280 +                 matrix (<span style="color: #8cd0d3;">first</span> args)
  35.281 +                 scalar (<span style="color: #8cd0d3;">second</span> args)]
  35.282 +             (incanter.core/matrix (<span style="color: #8cd0d3;">map</span> (<span style="color: #8cd0d3;">partial</span> map (<span style="color: #8cd0d3;">partial</span> multiply scalar)) matrix))))
  35.283 +           
  35.284 +</pre>
  35.285 +
  35.286 +
  35.287 +
  35.288 +
  35.289 +
  35.290 +</div>
  35.291 +
  35.292 +</div>
  35.293 +
  35.294 +<div id="outline-container-2" class="outline-2">
  35.295 +<h2 id="sec-2"><span class="section-number-2">2</span> Useful Data Types </h2>
  35.296 +<div class="outline-text-2" id="text-2">
  35.297 +
  35.298 +
  35.299 +
  35.300 +</div>
  35.301 +
  35.302 +<div id="outline-container-2-1" class="outline-3">
  35.303 +<h3 id="sec-2-1"><span class="section-number-3">2.1</span> Complex Numbers </h3>
  35.304 +<div class="outline-text-3" id="text-2-1">
  35.305 +
  35.306 +
  35.307 +
  35.308 +
  35.309 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  35.310 +
  35.311 +(<span style="color: #f0dfaf; font-weight: bold;">defprotocol</span> <span style="color: #f0dfaf;">Complex</span>
  35.312 +  (real-part [z])
  35.313 +  (imaginary-part [z])
  35.314 +  (magnitude-squared [z])
  35.315 +  (angle [z])
  35.316 +  (conjugate [z])
  35.317 +  (norm [z]))
  35.318 +
  35.319 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">complex-rectangular</span>
  35.320 +  <span style="color: #8fb28f;">"Define a complex number with the given real and imaginary</span>
  35.321 +<span style="color: #8fb28f;">  components."</span>
  35.322 +  [re im]
  35.323 +  (<span style="color: #8cd0d3;">reify</span> Complex
  35.324 +         (real-part [z] re)
  35.325 +         (imaginary-part [z] im)
  35.326 +         (magnitude-squared [z] (<span style="color: #8cd0d3;">+</span> (<span style="color: #8cd0d3;">*</span> re re) (<span style="color: #8cd0d3;">*</span> im im)))
  35.327 +         (angle [z] (java.lang.Math/atan2 im re))
  35.328 +         (conjugate [z] (complex-rectangular re (<span style="color: #8cd0d3;">-</span> im)))
  35.329 +
  35.330 +         Arithmetic
  35.331 +         (zero [z] (complex-rectangular 0 0))
  35.332 +         (one [z] (complex-rectangular 1 0))
  35.333 +         (negate [z] (complex-rectangular (<span style="color: #8cd0d3;">-</span> re) (<span style="color: #8cd0d3;">-</span> im)))
  35.334 +         (invert [z] (complex-rectangular
  35.335 +                      (<span style="color: #8cd0d3;">/</span> re (magnitude-squared z))
  35.336 +                      (<span style="color: #8cd0d3;">/</span> (<span style="color: #8cd0d3;">-</span> im) (magnitude-squared z))))
  35.337 +
  35.338 +         Object
  35.339 +         (toString [_]
  35.340 +                   (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #f0dfaf; font-weight: bold;">and</span> (zero? re) (zero? im)) (<span style="color: #8cd0d3;">str</span> 0)
  35.341 +                       (<span style="color: #8cd0d3;">str</span>
  35.342 +                        (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not</span>(zero? re))
  35.343 +                          re)
  35.344 +                        (<span style="color: #f0dfaf; font-weight: bold;">if</span> ((<span style="color: #8cd0d3;">comp</span> not zero?) im)
  35.345 +                          (<span style="color: #8cd0d3;">str</span>
  35.346 +                           (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">neg?</span> im) <span style="color: #cc9393;">"-"</span> <span style="color: #cc9393;">"+"</span>)
  35.347 +                           (<span style="color: #f0dfaf; font-weight: bold;">if</span> ((<span style="color: #8cd0d3;">comp</span> not one?) (java.lang.Math/abs im))
  35.348 +                           (java.lang.Math/abs im))
  35.349 +                           <span style="color: #cc9393;">"i"</span>)))))))
  35.350 +
  35.351 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">complex-polar</span>
  35.352 +  <span style="color: #8fb28f;">"Define a complex number with the given magnitude and angle."</span>
  35.353 +  [mag ang]
  35.354 +  (<span style="color: #8cd0d3;">reify</span> Complex
  35.355 +         (magnitude-squared [z] (<span style="color: #8cd0d3;">*</span> mag mag))
  35.356 +         (angle [z] angle)
  35.357 +         (real-part [z] (<span style="color: #8cd0d3;">*</span> mag (java.lang.Math/cos ang)))
  35.358 +         (imaginary-part [z] (<span style="color: #8cd0d3;">*</span> mag (java.lang.Math/sin ang)))
  35.359 +         (conjugate [z] (complex-polar mag (<span style="color: #8cd0d3;">-</span> ang)))
  35.360 +
  35.361 +         Arithmetic
  35.362 +         (zero [z] (complex-polar 0 0))
  35.363 +         (one [z] (complex-polar 1 0))
  35.364 +         (negate [z] (complex-polar (<span style="color: #8cd0d3;">-</span> mag) ang))
  35.365 +         (invert [z] (complex-polar (<span style="color: #8cd0d3;">/</span> mag) (<span style="color: #8cd0d3;">-</span> ang)))
  35.366 +
  35.367 +         Object
  35.368 +         (toString [_] (<span style="color: #8cd0d3;">str</span> mag <span style="color: #cc9393;">" * e^(i"</span> ang<span style="color: #cc9393;">")"</span>))
  35.369 +         ))
  35.370 +
  35.371 +
  35.372 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">Numbers are complex quantities</span>
  35.373 +
  35.374 +(<span style="color: #8cd0d3;">extend-protocol</span> Complex
  35.375 +  java.lang.Number
  35.376 +  (real-part [x] x)
  35.377 +  (imaginary-part [x] 0)
  35.378 +  (magnitude [x] x)
  35.379 +  (angle [x] 0)
  35.380 +  (conjugate [x] x))
  35.381 +
  35.382 +
  35.383 +</pre>
  35.384 +
  35.385 +
  35.386 +
  35.387 +
  35.388 +
  35.389 +
  35.390 +</div>
  35.391 +
  35.392 +</div>
  35.393 +
  35.394 +<div id="outline-container-2-2" class="outline-3">
  35.395 +<h3 id="sec-2-2"><span class="section-number-3">2.2</span> Tuples and Tensors </h3>
  35.396 +<div class="outline-text-3" id="text-2-2">
  35.397 +
  35.398 +
  35.399 +<p>
  35.400 +A tuple is a vector which is spinable&mdash;it can be either <i>spin up</i> or <i>spin down</i>. (Covariant, contravariant; dual vectors)
  35.401 +</p>
  35.402 +
  35.403 +
  35.404 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  35.405 +
  35.406 +(<span style="color: #f0dfaf; font-weight: bold;">defprotocol</span> <span style="color: #f0dfaf;">Spinning</span>
  35.407 +  (up? [this])
  35.408 +  (down? [this]))
  35.409 +
  35.410 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">spin</span>
  35.411 +  <span style="color: #8fb28f;">"Returns the spin of the Spinning s, either :up or :down"</span>
  35.412 +  [<span style="color: #dfdfbf; font-weight: bold;">#^Spinning</span> s]
  35.413 +  (<span style="color: #f0dfaf; font-weight: bold;">cond</span> (up? s) <span style="color: #8cd0d3;">:up</span> (down? s) <span style="color: #8cd0d3;">:down</span>))
  35.414 +
  35.415 +
  35.416 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">Tuple</span>
  35.417 +  [spin coll]
  35.418 +  clojure.lang.Seqable
  35.419 +  (<span style="color: #8cd0d3;">seq</span> [this] (<span style="color: #8cd0d3;">seq</span> (.coll this)))
  35.420 +  clojure.lang.Counted
  35.421 +  (<span style="color: #8cd0d3;">count</span> [this] (<span style="color: #8cd0d3;">count</span> (.coll this))))
  35.422 +
  35.423 +(<span style="color: #8cd0d3;">extend-type</span> Tuple
  35.424 +  Spinning
  35.425 +  (up? [this] (<span style="color: #8cd0d3;">=</span> <span style="color: #8cd0d3;">::up</span> (.spin this)))
  35.426 +  (down? [this] (<span style="color: #8cd0d3;">=</span> <span style="color: #8cd0d3;">::down</span> (.spin this))))
  35.427 +
  35.428 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">print-method</span> Tuple
  35.429 +  [o w]
  35.430 +  (<span style="color: #8cd0d3;">print-simple</span> (<span style="color: #8cd0d3;">str</span> (<span style="color: #f0dfaf; font-weight: bold;">if</span> (up? o) 'u 'd) (.coll o))  w))
  35.431 +
  35.432 +
  35.433 +
  35.434 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">up</span>
  35.435 +  <span style="color: #8fb28f;">"Create a new up-tuple containing the contents of coll."</span>
  35.436 +  [coll]
  35.437 +  (Tuple. <span style="color: #8cd0d3;">::up</span> coll))       
  35.438 +
  35.439 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">down</span>
  35.440 +  <span style="color: #8fb28f;">"Create a new down-tuple containing the contents of coll."</span>
  35.441 +  [coll]
  35.442 +  (Tuple. <span style="color: #8cd0d3;">::down</span> coll))
  35.443 +
  35.444 +
  35.445 +</pre>
  35.446 +
  35.447 +
  35.448 +
  35.449 +
  35.450 +
  35.451 +</div>
  35.452 +
  35.453 +<div id="outline-container-2-2-1" class="outline-4">
  35.454 +<h4 id="sec-2-2-1"><span class="section-number-4">2.2.1</span> Contraction </h4>
  35.455 +<div class="outline-text-4" id="text-2-2-1">
  35.456 +
  35.457 +<p>Contraction is a binary operation that you can apply to compatible
  35.458 + tuples. Tuples are compatible for contraction if they have the same
  35.459 + length and opposite spins, and if the corresponding items in each
  35.460 + tuple are both numbers or both compatible tuples.
  35.461 +</p>
  35.462 +
  35.463 +
  35.464 +
  35.465 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  35.466 +
  35.467 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">numbers?</span>
  35.468 +  <span style="color: #8fb28f;">"Returns true if all arguments are numbers, else false."</span>
  35.469 +  [&amp; xs]
  35.470 +  (<span style="color: #8cd0d3;">every?</span> number? xs))
  35.471 +
  35.472 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">contractible?</span>
  35.473 +  <span style="color: #8fb28f;">"Returns true if the tuples a and b are compatible for contraction,</span>
  35.474 +<span style="color: #8fb28f;">  else false. Tuples are compatible if they have the same number of</span>
  35.475 +<span style="color: #8fb28f;">  components, they have opposite spins, and their elements are</span>
  35.476 +<span style="color: #8fb28f;">  pairwise-compatible."</span>
  35.477 +  [a b]
  35.478 +  (<span style="color: #f0dfaf; font-weight: bold;">and</span>
  35.479 +   (<span style="color: #8cd0d3;">isa?</span> (<span style="color: #8cd0d3;">type</span> a) Tuple)
  35.480 +   (<span style="color: #8cd0d3;">isa?</span> (<span style="color: #8cd0d3;">type</span> b) Tuple)
  35.481 +   (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">count</span> a) (<span style="color: #8cd0d3;">count</span> b))
  35.482 +   (<span style="color: #8cd0d3;">not=</span> (spin a) (spin b))
  35.483 +   
  35.484 +   (<span style="color: #8cd0d3;">not-any?</span> false?
  35.485 +             (<span style="color: #8cd0d3;">map</span> #(<span style="color: #f0dfaf; font-weight: bold;">or</span>
  35.486 +                    (numbers? %1 %2)
  35.487 +                    (contractible? %1 %2))
  35.488 +                  a b))))
  35.489 +
  35.490 +
  35.491 +
  35.492 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">contract</span>
  35.493 +  <span style="color: #8fb28f;">"Contracts two tuples, returning the sum of the</span>
  35.494 +<span style="color: #8fb28f;">  products of the corresponding items. Contraction is recursive on</span>
  35.495 +<span style="color: #8fb28f;">  nested tuples."</span>
  35.496 +  [a b]
  35.497 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not</span> (contractible? a b))
  35.498 +    (<span style="color: #f0dfaf; font-weight: bold;">throw</span>
  35.499 +     (Exception. <span style="color: #cc9393;">"Not compatible for contraction."</span>))
  35.500 +    (<span style="color: #8cd0d3;">reduce</span> +
  35.501 +            (<span style="color: #8cd0d3;">map</span>
  35.502 +             (<span style="color: #8cd0d3;">fn</span> [x y]
  35.503 +               (<span style="color: #f0dfaf; font-weight: bold;">if</span> (numbers? x y)
  35.504 +                 (<span style="color: #8cd0d3;">*</span> x y)
  35.505 +                 (contract x y)))
  35.506 +             a b))))
  35.507 +
  35.508 +</pre>
  35.509 +
  35.510 +
  35.511 +
  35.512 +
  35.513 +</div>
  35.514 +
  35.515 +</div>
  35.516 +
  35.517 +<div id="outline-container-2-2-2" class="outline-4">
  35.518 +<h4 id="sec-2-2-2"><span class="section-number-4">2.2.2</span> Matrices </h4>
  35.519 +<div class="outline-text-4" id="text-2-2-2">
  35.520 +
  35.521 +
  35.522 +
  35.523 +
  35.524 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  35.525 +(<span style="color: #8cd0d3;">require</span> 'incanter.core) <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">use incanter's fast matrices</span>
  35.526 +
  35.527 +(<span style="color: #f0dfaf; font-weight: bold;">defprotocol</span> <span style="color: #f0dfaf;">Matrix</span>
  35.528 +  (rows [matrix])
  35.529 +  (cols [matrix])
  35.530 +  (diagonal [matrix])
  35.531 +  (trace [matrix])
  35.532 +  (determinant [matrix])
  35.533 +  (transpose [matrix])
  35.534 +  (conjugate [matrix])
  35.535 +)
  35.536 +
  35.537 +(<span style="color: #8cd0d3;">extend-protocol</span> Matrix
  35.538 +  incanter.Matrix
  35.539 +  (rows [rs] (<span style="color: #8cd0d3;">map</span> down (<span style="color: #8cd0d3;">apply</span> map vector (<span style="color: #8cd0d3;">apply</span> map vector rs))))
  35.540 +  (cols [rs] (<span style="color: #8cd0d3;">map</span> up (<span style="color: #8cd0d3;">apply</span> map vector rs)))
  35.541 +  (diagonal [matrix] (incanter.core/diag matrix) )
  35.542 +  (determinant [matrix] (incanter.core/det matrix))
  35.543 +  (trace [matrix] (incanter.core/trace matrix))
  35.544 +  (transpose [matrix] (incanter.core/trans matrix))
  35.545 +  )
  35.546 +
  35.547 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">count-rows</span> [matrix]
  35.548 +  ((<span style="color: #8cd0d3;">comp</span> count rows) matrix))
  35.549 +
  35.550 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">count-cols</span> [matrix]
  35.551 +  ((<span style="color: #8cd0d3;">comp</span> count cols) matrix))
  35.552 +
  35.553 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">square?</span> [matrix]
  35.554 +  (<span style="color: #8cd0d3;">=</span> (count-rows matrix) (count-cols matrix)))
  35.555 +
  35.556 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">identity-matrix</span>
  35.557 +  <span style="color: #8fb28f;">"Define a square matrix of size n-by-n with 1s along the diagonal and</span>
  35.558 +<span style="color: #8fb28f;">  0s everywhere else."</span>
  35.559 +  [n]
  35.560 +  (incanter.core/identity-matrix n))
  35.561 +
  35.562 +
  35.563 +
  35.564 +
  35.565 +
  35.566 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">matrix-by-rows</span>
  35.567 +  <span style="color: #8fb28f;">"Define a matrix by giving its rows."</span>
  35.568 +  [&amp; rows]
  35.569 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span>
  35.570 +   (<span style="color: #8cd0d3;">not</span> (all-equal? (<span style="color: #8cd0d3;">map</span> count rows)))
  35.571 +   (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"All rows in a matrix must have the same number of elements."</span>))
  35.572 +   (incanter.core/matrix (<span style="color: #8cd0d3;">vec</span> rows))))
  35.573 +
  35.574 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">matrix-by-cols</span>
  35.575 +  <span style="color: #8fb28f;">"Define a matrix by giving its columns"</span>
  35.576 +  [&amp; cols]
  35.577 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not</span> (all-equal? (<span style="color: #8cd0d3;">map</span> count cols)))
  35.578 +   (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"All columns in a matrix must have the same number of elements."</span>))
  35.579 +   (incanter.core/matrix (<span style="color: #8cd0d3;">vec</span> (<span style="color: #8cd0d3;">apply</span> map vector cols)))))
  35.580 +
  35.581 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">identity-matrix</span>
  35.582 +  <span style="color: #8fb28f;">"Define a square matrix of size n-by-n with 1s along the diagonal and</span>
  35.583 +<span style="color: #8fb28f;">  0s everywhere else."</span>
  35.584 +  [n]
  35.585 +  (incanter.core/identity-matrix n))
  35.586 +
  35.587 +
  35.588 +
  35.589 +(<span style="color: #8cd0d3;">extend-protocol</span> Arithmetic
  35.590 +  incanter.Matrix
  35.591 +  (one [matrix]
  35.592 +       (<span style="color: #f0dfaf; font-weight: bold;">if</span> (square? matrix)
  35.593 +         (identity-matrix (count-rows matrix))
  35.594 +         (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"Non-square matrices have no multiplicative unit."</span>))))
  35.595 +  (zero [matrix]
  35.596 +        (<span style="color: #8cd0d3;">apply</span> matrix-by-rows (<span style="color: #8cd0d3;">map</span> zero (rows matrix))))
  35.597 +  (negate [matrix]
  35.598 +          (<span style="color: #8cd0d3;">apply</span> matrix-by-rows (<span style="color: #8cd0d3;">map</span> negate (rows matrix))))
  35.599 +  (invert [matrix]
  35.600 +          (incanter.core/solve matrix)))
  35.601 +
  35.602 +
  35.603 +
  35.604 +(<span style="color: #f0dfaf; font-weight: bold;">defmulti</span> <span style="color: #f0dfaf;">coerce-to-matrix</span>
  35.605 + <span style="color: #8fb28f;">"Converts x into a matrix, if possible."</span>
  35.606 + type)
  35.607 +
  35.608 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">coerce-to-matrix</span> incanter.Matrix [x] x)
  35.609 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">coerce-to-matrix</span> Tuple [x]
  35.610 +           (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">apply</span> numbers? (<span style="color: #8cd0d3;">seq</span> x))
  35.611 +             (<span style="color: #f0dfaf; font-weight: bold;">if</span> (up? x)
  35.612 +             (matrix-by-cols (<span style="color: #8cd0d3;">seq</span> x))
  35.613 +             (matrix-by-rows (<span style="color: #8cd0d3;">seq</span> x)))
  35.614 +             (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"Non-numerical tuple cannot be converted into a matrix."</span>)))) 
  35.615 +             
  35.616 +  
  35.617 +
  35.618 +
  35.619 +
  35.620 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">(defn matrix-by-cols</span>
  35.621 +<span style="color: #708070;">;;   </span><span style="color: #7f9f7f;">"Define a matrix by giving its columns."</span>
  35.622 +<span style="color: #708070;">;;   </span><span style="color: #7f9f7f;">[&amp; cols]</span>
  35.623 +<span style="color: #708070;">;;   </span><span style="color: #7f9f7f;">(cond</span>
  35.624 +<span style="color: #708070;">;;    </span><span style="color: #7f9f7f;">(not (all-equal? (map count cols)))</span>
  35.625 +<span style="color: #708070;">;;    </span><span style="color: #7f9f7f;">(throw (Exception. "All columns in a matrix must have the same number of elements."))</span>
  35.626 +<span style="color: #708070;">;;    </span><span style="color: #7f9f7f;">:else</span>
  35.627 +<span style="color: #708070;">;;    </span><span style="color: #7f9f7f;">(reify Matrix</span>
  35.628 +<span style="color: #708070;">;;        </span><span style="color: #7f9f7f;">(cols [this] (map up cols))</span>
  35.629 +<span style="color: #708070;">;;        </span><span style="color: #7f9f7f;">(rows [this] (map down (apply map vector cols)))</span>
  35.630 +<span style="color: #708070;">;;        </span><span style="color: #7f9f7f;">(diagonal [this] (map-indexed (fn [i col] (nth col i) cols)))</span>
  35.631 +<span style="color: #708070;">;;        </span><span style="color: #7f9f7f;">(trace [this]</span>
  35.632 +<span style="color: #708070;">;;               </span><span style="color: #7f9f7f;">(if (not= (count-cols this) (count-rows this))</span>
  35.633 +<span style="color: #708070;">;;                 </span><span style="color: #7f9f7f;">(throw (Exception.</span>
  35.634 +<span style="color: #708070;">;;                         </span><span style="color: #7f9f7f;">"Cannot take the trace of a non-square matrix."))</span>
  35.635 +<span style="color: #708070;">;;                 </span><span style="color: #7f9f7f;">(reduce + (diagonal this))))</span>
  35.636 +          
  35.637 +<span style="color: #708070;">;;        </span><span style="color: #7f9f7f;">(determinant [this]</span>
  35.638 +<span style="color: #708070;">;;                     </span><span style="color: #7f9f7f;">(if (not= (count-cols this) (count-rows this))</span>
  35.639 +<span style="color: #708070;">;;                       </span><span style="color: #7f9f7f;">(throw (Exception.</span>
  35.640 +<span style="color: #708070;">;;                               </span><span style="color: #7f9f7f;">"Cannot take the determinant of a non-square matrix."))</span>
  35.641 +<span style="color: #708070;">;;                       </span><span style="color: #7f9f7f;">(reduce * (map-indexed (fn [i col] (nth col i)) cols))))</span>
  35.642 +<span style="color: #708070;">;;        </span><span style="color: #7f9f7f;">)))</span>
  35.643 +
  35.644 +(<span style="color: #8cd0d3;">extend-protocol</span> Matrix  Tuple
  35.645 +                 (rows [this] (<span style="color: #f0dfaf; font-weight: bold;">if</span> (down? this)
  35.646 +                                (<span style="color: #8cd0d3;">list</span> this)
  35.647 +                                (<span style="color: #8cd0d3;">map</span> (<span style="color: #8cd0d3;">comp</span> up vector) this)))
  35.648 +
  35.649 +                 (cols [this] (<span style="color: #f0dfaf; font-weight: bold;">if</span> (up? this)
  35.650 +                                (<span style="color: #8cd0d3;">list</span> this)
  35.651 +                                (<span style="color: #8cd0d3;">map</span> (<span style="color: #8cd0d3;">comp</span> down vector) this))
  35.652 +                 ))
  35.653 +  
  35.654 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">matrix-multiply</span>
  35.655 +  <span style="color: #8fb28f;">"Returns the matrix resulting from the matrix multiplication of the given arguments."</span>
  35.656 +  ([A] (coerce-to-matrix A))
  35.657 +  ([A B] (incanter.core/mmult (coerce-to-matrix A) (coerce-to-matrix B)))
  35.658 +  ([M1 M2 &amp; Ms] (<span style="color: #8cd0d3;">reduce</span> matrix-multiply (matrix-multiply M1 M2) Ms)))
  35.659 +
  35.660 +</pre>
  35.661 +
  35.662 +
  35.663 +
  35.664 +
  35.665 +
  35.666 +</div>
  35.667 +</div>
  35.668 +
  35.669 +</div>
  35.670 +
  35.671 +<div id="outline-container-2-3" class="outline-3">
  35.672 +<h3 id="sec-2-3"><span class="section-number-3">2.3</span> Power Series </h3>
  35.673 +<div class="outline-text-3" id="text-2-3">
  35.674 +
  35.675 +
  35.676 +
  35.677 +
  35.678 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  35.679 +(<span style="color: #8cd0d3;">use</span> 'clojure.contrib.def)
  35.680 +
  35.681 +
  35.682 +
  35.683 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">series-fn</span>
  35.684 +  <span style="color: #8fb28f;">"The function corresponding to the given power series."</span>
  35.685 +  [series]
  35.686 +  (<span style="color: #8cd0d3;">fn</span> [x]
  35.687 +    (<span style="color: #8cd0d3;">reduce</span> +
  35.688 +            (map-indexed  (<span style="color: #8cd0d3;">fn</span>[n x] (<span style="color: #8cd0d3;">*</span> (<span style="color: #8cd0d3;">float</span> (<span style="color: #8cd0d3;">nth</span> series n)) (<span style="color: #8cd0d3;">float</span>(java.lang.Math/pow (<span style="color: #8cd0d3;">float</span> x) n)) ))
  35.689 +                          (<span style="color: #8cd0d3;">range</span> 20)))))
  35.690 +
  35.691 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">PowerSeries</span>
  35.692 +  [coll]
  35.693 +  clojure.lang.Seqable
  35.694 +  (<span style="color: #8cd0d3;">seq</span> [this] (<span style="color: #8cd0d3;">seq</span> (.coll this)))
  35.695 +  
  35.696 +  clojure.lang.Indexed
  35.697 +  (<span style="color: #8cd0d3;">nth</span> [this n] (<span style="color: #8cd0d3;">nth</span> (.coll this) n 0))
  35.698 +  (<span style="color: #8cd0d3;">nth</span> [this n not-found] (<span style="color: #8cd0d3;">nth</span> (.coll this) n not-found))
  35.699 +
  35.700 +  <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">clojure.lang.IFn</span>
  35.701 +  <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">(call [this] (throw(Exception.)))</span>
  35.702 +  <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">(invoke [this &amp; args] args</span>
  35.703 +  <span style="color: #708070;">;;      </span><span style="color: #7f9f7f;">(let [f </span>
  35.704 +  <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">)</span>
  35.705 +  <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">(run [this] (throw(Exception.)))</span>
  35.706 +  )
  35.707 +
  35.708 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">power-series</span>
  35.709 +  <span style="color: #8fb28f;">"Returns a power series with the items of the coll as its</span>
  35.710 +<span style="color: #8fb28f;">  coefficients. Trailing zeros are added to the end of coll."</span>
  35.711 +  [coeffs]
  35.712 +  (PowerSeries. coeffs))
  35.713 +
  35.714 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">power-series-indexed</span>
  35.715 +  <span style="color: #8fb28f;">"Returns a power series consisting of the result of mapping f to the non-negative integers."</span>
  35.716 +  [f]
  35.717 +  (PowerSeries. (<span style="color: #8cd0d3;">map</span> f (<span style="color: #8cd0d3;">range</span>))))
  35.718 +
  35.719 +
  35.720 +(<span style="color: #f0dfaf; font-weight: bold;">defn-memo</span> <span style="color: #f0dfaf;">nth-partial-sum</span>
  35.721 +  ([series n]
  35.722 +     (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? n) (<span style="color: #8cd0d3;">first</span> series)
  35.723 +         (<span style="color: #8cd0d3;">+</span> (<span style="color: #8cd0d3;">nth</span> series n)
  35.724 +            (nth-partial-sum series (<span style="color: #8cd0d3;">dec</span> n))))))
  35.725 +
  35.726 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">partial-sums</span> [series]
  35.727 +  (<span style="color: #8cd0d3;">lazy-seq</span> (<span style="color: #8cd0d3;">map</span> nth-partial-sum (<span style="color: #8cd0d3;">range</span>))))
  35.728 +
  35.729 +
  35.730 +
  35.731 +
  35.732 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">cos-series</span>
  35.733 +     (power-series-indexed
  35.734 +      (<span style="color: #8cd0d3;">fn</span>[n]
  35.735 +        (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">odd?</span> n) 0
  35.736 +            (<span style="color: #8cd0d3;">/</span>
  35.737 +             (<span style="color: #8cd0d3;">reduce</span> *
  35.738 +                     (<span style="color: #8cd0d3;">reduce</span> * (<span style="color: #8cd0d3;">repeat</span> (<span style="color: #8cd0d3;">/</span> n 2) -1))
  35.739 +                     (<span style="color: #8cd0d3;">range</span> 1 (<span style="color: #8cd0d3;">inc</span> n)))
  35.740 +             )))))
  35.741 +
  35.742 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">sin-series</span>
  35.743 +     (power-series-indexed
  35.744 +      (<span style="color: #8cd0d3;">fn</span>[n]
  35.745 +        (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">even?</span> n) 0
  35.746 +            (<span style="color: #8cd0d3;">/</span>
  35.747 +             (<span style="color: #8cd0d3;">reduce</span> *
  35.748 +                     (<span style="color: #8cd0d3;">reduce</span> * (<span style="color: #8cd0d3;">repeat</span> (<span style="color: #8cd0d3;">/</span> (<span style="color: #8cd0d3;">dec</span> n) 2) -1))
  35.749 +                     (<span style="color: #8cd0d3;">range</span> 1 (<span style="color: #8cd0d3;">inc</span> n)))
  35.750 +             )))))
  35.751 +
  35.752 +</pre>
  35.753 +
  35.754 +
  35.755 +
  35.756 +
  35.757 +
  35.758 +</div>
  35.759 +</div>
  35.760 +
  35.761 +</div>
  35.762 +
  35.763 +<div id="outline-container-3" class="outline-2">
  35.764 +<h2 id="sec-3"><span class="section-number-2">3</span> Basic Utilities </h2>
  35.765 +<div class="outline-text-2" id="text-3">
  35.766 +
  35.767 +
  35.768 +
  35.769 +</div>
  35.770 +
  35.771 +<div id="outline-container-3-1" class="outline-3">
  35.772 +<h3 id="sec-3-1"><span class="section-number-3">3.1</span> Sequence manipulation </h3>
  35.773 +<div class="outline-text-3" id="text-3-1">
  35.774 +
  35.775 +
  35.776 +
  35.777 +
  35.778 +
  35.779 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">ns</span> sicm.utils)
  35.780 +
  35.781 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">do-up</span>
  35.782 +  <span style="color: #8fb28f;">"Apply f to each number from low to high, presumably for</span>
  35.783 +<span style="color: #8fb28f;">  side-effects."</span>
  35.784 +  [f low high]
  35.785 +  (<span style="color: #f0dfaf; font-weight: bold;">doseq</span> [i (<span style="color: #8cd0d3;">range</span> low high)] (f i)))
  35.786 +   
  35.787 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">do-down</span>
  35.788 +  <span style="color: #8fb28f;">"Apply f to each number from high to low, presumably for</span>
  35.789 +<span style="color: #8fb28f;">   side-effects."</span>
  35.790 +  [f high low]
  35.791 +  (<span style="color: #f0dfaf; font-weight: bold;">doseq</span> [i (<span style="color: #8cd0d3;">range</span> high low -1)] (f i)))
  35.792 +
  35.793 +
  35.794 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">all-equal?</span> [coll]
  35.795 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">empty?</span> (<span style="color: #8cd0d3;">rest</span> coll)) true
  35.796 +      (<span style="color: #f0dfaf; font-weight: bold;">and</span> (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">first</span> coll) (<span style="color: #8cd0d3;">second</span> coll))
  35.797 +           (<span style="color: #f0dfaf; font-weight: bold;">recur</span> (<span style="color: #8cd0d3;">rest</span> coll))))))
  35.798 +
  35.799 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">multiplier</span>
  35.800 +  <span style="color: #8fb28f;">"Returns a function that 'multiplies' the members of a collection,</span>
  35.801 +<span style="color: #8fb28f;">returning unit if called on an empty collection."</span>
  35.802 +  [multiply unit]
  35.803 +  (<span style="color: #8cd0d3;">fn</span> [coll] ((<span style="color: #8cd0d3;">partial</span> reduce multiply unit) coll)))
  35.804 +
  35.805 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">divider</span>
  35.806 +  <span style="color: #8fb28f;">"Returns a function that 'divides' the first element of a collection</span>
  35.807 +<span style="color: #8fb28f;">by the 'product' of the rest of the collection."</span>
  35.808 +  [divide multiply invert unit]
  35.809 +  (<span style="color: #8cd0d3;">fn</span> [coll]
  35.810 +    (<span style="color: #8cd0d3;">apply</span>
  35.811 +     (<span style="color: #8cd0d3;">fn</span>
  35.812 +       ([] unit)
  35.813 +       ([x] (invert x))
  35.814 +       ([x y] (divide x y))
  35.815 +       ([x y &amp; zs] (divide x (<span style="color: #8cd0d3;">reduce</span> multiply y zs))))
  35.816 +     coll)))
  35.817 +
  35.818 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">left-circular-shift</span>
  35.819 +  <span style="color: #8fb28f;">"Remove the first element of coll, adding it to the end of coll."</span>
  35.820 +  [coll]
  35.821 +  (<span style="color: #8cd0d3;">concat</span> (<span style="color: #8cd0d3;">rest</span> coll) (<span style="color: #8cd0d3;">take</span> 1 coll)))
  35.822 +
  35.823 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">right-circular-shift</span>
  35.824 +  <span style="color: #8fb28f;">"Remove the last element of coll, adding it to the front of coll."</span>
  35.825 +  [coll]
  35.826 +  (<span style="color: #8cd0d3;">cons</span> (<span style="color: #8cd0d3;">last</span> coll) (<span style="color: #8cd0d3;">butlast</span> coll)))
  35.827 +</pre>
  35.828 +
  35.829 +
  35.830 +
  35.831 +
  35.832 +
  35.833 +
  35.834 +
  35.835 +</div>
  35.836 +
  35.837 +</div>
  35.838 +
  35.839 +<div id="outline-container-3-2" class="outline-3">
  35.840 +<h3 id="sec-3-2"><span class="section-number-3">3.2</span> Ranges, Airity and Function Composition </h3>
  35.841 +<div class="outline-text-3" id="text-3-2">
  35.842 +
  35.843 +
  35.844 +
  35.845 +
  35.846 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  35.847 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">infinity</span> Double/POSITIVE_INFINITY)
  35.848 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">infinite?</span> [x] (Double/isInfinite x))
  35.849 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">finite?</span> (<span style="color: #8cd0d3;">comp</span> not infinite?)) 
  35.850 +
  35.851 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">arity-min</span>
  35.852 +  <span style="color: #8fb28f;">"Returns the smallest number of arguments f can take."</span>
  35.853 +  [f]
  35.854 +  (<span style="color: #8cd0d3;">apply</span>
  35.855 +   min
  35.856 +   (<span style="color: #8cd0d3;">map</span> (<span style="color: #8cd0d3;">comp</span> alength #(.getParameterTypes %))
  35.857 +        (<span style="color: #8cd0d3;">filter</span> (<span style="color: #8cd0d3;">comp</span> (<span style="color: #8cd0d3;">partial</span> = <span style="color: #cc9393;">"invoke"</span>) #(.getName %))
  35.858 +                (.getDeclaredMethods (<span style="color: #8cd0d3;">class</span> f))))))
  35.859 +  
  35.860 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">arity-max</span>
  35.861 +  <span style="color: #8fb28f;">"Returns the largest number of arguments f can take, possibly</span>
  35.862 +<span style="color: #8fb28f;">  Infinity."</span>
  35.863 +  [f]
  35.864 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [methods (.getDeclaredMethods (<span style="color: #8cd0d3;">class</span> f))]
  35.865 +    (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not-any?</span> (<span style="color: #8cd0d3;">partial</span> = <span style="color: #cc9393;">"doInvoke"</span>) (<span style="color: #8cd0d3;">map</span> #(.getName %) methods))
  35.866 +      (<span style="color: #8cd0d3;">apply</span> max
  35.867 +             (<span style="color: #8cd0d3;">map</span> (<span style="color: #8cd0d3;">comp</span> alength #(.getParameterTypes %))
  35.868 +                  (<span style="color: #8cd0d3;">filter</span> (<span style="color: #8cd0d3;">comp</span> (<span style="color: #8cd0d3;">partial</span> = <span style="color: #cc9393;">"invoke"</span>) #(.getName %))  methods)))
  35.869 +      infinity)))
  35.870 +
  35.871 +
  35.872 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">^</span>{<span style="color: #8cd0d3;">:arglists</span> '([f])
  35.873 +       <span style="color: #8cd0d3;">:doc</span> <span style="color: #cc9393;">"Returns a two-element list containing the minimum and</span>
  35.874 +<span style="color: #cc9393;">     maximum number of args that f can take."</span>}
  35.875 +     arity-interval
  35.876 +     (<span style="color: #8cd0d3;">juxt</span> arity-min arity-max))
  35.877 +
  35.878 +
  35.879 +
  35.880 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">--- intervals</span>
  35.881 +
  35.882 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">intersect</span>
  35.883 +  <span style="color: #8fb28f;">"Returns the interval of overlap between interval-1 and interval-2"</span>
  35.884 +  [interval-1 interval-2]
  35.885 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #f0dfaf; font-weight: bold;">or</span> (<span style="color: #8cd0d3;">empty?</span> interval-1) (<span style="color: #8cd0d3;">empty?</span> interval-2)) []
  35.886 +      (<span style="color: #f0dfaf; font-weight: bold;">let</span> [left (<span style="color: #8cd0d3;">max</span> (<span style="color: #8cd0d3;">first</span> interval-1) (<span style="color: #8cd0d3;">first</span> interval-2))
  35.887 +            right (<span style="color: #8cd0d3;">min</span> (<span style="color: #8cd0d3;">second</span> interval-1) (<span style="color: #8cd0d3;">second</span> interval-2))]
  35.888 +        (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">&gt;</span> left right) []
  35.889 +            [left right]))))
  35.890 +
  35.891 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">same-endpoints?</span>
  35.892 +  <span style="color: #8fb28f;">"Returns true if the left endpoint is the same as the right</span>
  35.893 +<span style="color: #8fb28f;">  endpoint."</span>
  35.894 +  [interval]
  35.895 +  (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">first</span> interval) (<span style="color: #8cd0d3;">second</span> interval)))
  35.896 +
  35.897 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">naturals?</span>
  35.898 +  <span style="color: #8fb28f;">"Returns true if the left endpoint is 0 and the right endpoint is</span>
  35.899 +<span style="color: #8fb28f;">infinite."</span>
  35.900 +  [interval]
  35.901 +  (<span style="color: #f0dfaf; font-weight: bold;">and</span> (zero? (<span style="color: #8cd0d3;">first</span> interval))
  35.902 +       (infinite? (<span style="color: #8cd0d3;">second</span> interval))))
  35.903 + 
  35.904 +
  35.905 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fan-in</span>
  35.906 +  <span style="color: #8fb28f;">"Returns a function that pipes its input to each of the gs, then</span>
  35.907 +<span style="color: #8fb28f;">  applies f to the list of results. Consequently, f must be able to</span>
  35.908 +<span style="color: #8fb28f;">  take a number of arguments equal to the number of gs."</span>
  35.909 +  [f &amp; gs]
  35.910 +  (<span style="color: #8cd0d3;">fn</span> [&amp; args]
  35.911 +    (<span style="color: #8cd0d3;">apply</span> f (<span style="color: #8cd0d3;">apply</span> (<span style="color: #8cd0d3;">apply</span> juxt gs) args))))
  35.912 +
  35.913 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fan-in</span>
  35.914 +  <span style="color: #8fb28f;">"Returns a function that pipes its input to each of the gs, then applies f to the list of results. The resulting function takes any number of arguments, but will fail if given arguments that are incompatible with any of the gs."</span>
  35.915 +  [f &amp; gs]
  35.916 +  (<span style="color: #8cd0d3;">comp</span> (<span style="color: #8cd0d3;">partial</span> apply f) (<span style="color: #8cd0d3;">apply</span> juxt gs)))
  35.917 +
  35.918 +
  35.919 +
  35.920 +(<span style="color: #f0dfaf; font-weight: bold;">defmacro</span> <span style="color: #f0dfaf;">airty-blah-sad</span> [f n more?]
  35.921 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [syms (<span style="color: #8cd0d3;">vec</span> (<span style="color: #8cd0d3;">map</span> (<span style="color: #8cd0d3;">comp</span> gensym (<span style="color: #8cd0d3;">partial</span> str <span style="color: #cc9393;">"x"</span>)) (<span style="color: #8cd0d3;">range</span> n)))
  35.922 +         optional (<span style="color: #8cd0d3;">gensym</span> <span style="color: #cc9393;">"xs"</span>)]
  35.923 +    (<span style="color: #f0dfaf; font-weight: bold;">if</span> more?
  35.924 +      `(<span style="color: #8cd0d3;">fn</span> <span style="color: #f0dfaf;">~</span>(<span style="color: #8cd0d3;">conj</span> syms '&amp; optional)
  35.925 +         (<span style="color: #8cd0d3;">apply</span> ~f ~@syms ~optional))
  35.926 +      `(<span style="color: #8cd0d3;">fn</span> <span style="color: #f0dfaf;">~syms</span> (~f ~@syms)))))
  35.927 +
  35.928 +(<span style="color: #f0dfaf; font-weight: bold;">defmacro</span> <span style="color: #f0dfaf;">airt-whaa*</span> [f n more?]
  35.929 +  `(airty-blah-sad ~f ~n ~more?))
  35.930 +
  35.931 +
  35.932 +
  35.933 +
  35.934 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fan-in*</span>
  35.935 +  <span style="color: #8fb28f;">"Returns a function that pipes its input to each of the gs, then</span>
  35.936 +<span style="color: #8fb28f;">  applies f to the list of results. Unlike fan-in, fan-in* strictly</span>
  35.937 +<span style="color: #8fb28f;">  enforces arity: it will fail if the gs do not have compatible</span>
  35.938 +<span style="color: #8fb28f;">  arities."</span>
  35.939 +  [f &amp; gs]
  35.940 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [arity-in (<span style="color: #8cd0d3;">reduce</span> intersect (<span style="color: #8cd0d3;">map</span> arity-interval gs))
  35.941 +        left (<span style="color: #8cd0d3;">first</span> arity-in)
  35.942 +        right (<span style="color: #8cd0d3;">second</span> arity-in)
  35.943 +        composite (fan-in f gs)
  35.944 +        ]
  35.945 +    (<span style="color: #f0dfaf; font-weight: bold;">cond</span>
  35.946 +     (<span style="color: #8cd0d3;">empty?</span> arity-in)
  35.947 +     (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"Cannot compose functions with incompatible arities."</span>))
  35.948 +
  35.949 +     (<span style="color: #8cd0d3;">not</span>
  35.950 +      (<span style="color: #f0dfaf; font-weight: bold;">or</span> (<span style="color: #8cd0d3;">=</span> left right)
  35.951 +          (<span style="color: #f0dfaf; font-weight: bold;">and</span> (finite? left)
  35.952 +               (<span style="color: #8cd0d3;">=</span> right infinity))))
  35.953 +         
  35.954 +     (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception.
  35.955 +             <span style="color: #cc9393;">"Compose can only handle arities of the form [n n] or [n infinity]"</span>))
  35.956 +     <span style="color: #8cd0d3;">:else</span>
  35.957 +     (airty-blah-sad composite left (<span style="color: #8cd0d3;">=</span> right infinity)))))
  35.958 +    
  35.959 +
  35.960 +
  35.961 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">compose-n</span> <span style="color: #8fb28f;">"Compose any number of functions together."</span>
  35.962 +  ([] identity)
  35.963 +  ([f] f)
  35.964 +  ([f &amp; fs]
  35.965 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [fns (<span style="color: #8cd0d3;">cons</span> f fs)]
  35.966 +    (compose-bin (<span style="color: #8cd0d3;">reduce</span> fan-in (<span style="color: #8cd0d3;">butlast</span> fs)) (<span style="color: #8cd0d3;">last</span> fs))))
  35.967 +)
  35.968 +
  35.969 +
  35.970 +
  35.971 +
  35.972 +           
  35.973 +
  35.974 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">iterated</span>
  35.975 +  ([f n id] (<span style="color: #8cd0d3;">reduce</span> comp id (<span style="color: #8cd0d3;">repeat</span> n f)))
  35.976 +  ([f n] (<span style="color: #8cd0d3;">reduce</span> comp identity (<span style="color: #8cd0d3;">repeat</span> n f))))
  35.977 +
  35.978 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">iterate-until-stable</span>
  35.979 +  <span style="color: #8fb28f;">"Repeatedly applies f to x, returning the first result that is close</span>
  35.980 +<span style="color: #8fb28f;">enough to its predecessor."</span>
  35.981 +  [f close-enough? x]
  35.982 +  (<span style="color: #8cd0d3;">second</span> (swank.util/find-first
  35.983 +           (<span style="color: #8cd0d3;">partial</span> apply close-enough?)
  35.984 +           (<span style="color: #8cd0d3;">partition</span> 2 1 (<span style="color: #8cd0d3;">iterate</span> f x)))))
  35.985 +
  35.986 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">lexical&lt;</span> [x y]
  35.987 +  (<span style="color: #8cd0d3;">neg?</span> (<span style="color: #8cd0d3;">compare</span> (<span style="color: #8cd0d3;">str</span> x) (<span style="color: #8cd0d3;">str</span> y))))
  35.988 +
  35.989 +
  35.990 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">do-up</span>
  35.991 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">do-down</span>
  35.992 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">make-pairwise-test</span> comparator)
  35.993 +<span style="color: #708070;">;;</span><span style="color: #7f9f7f;">all-equal?</span>
  35.994 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">accumulation</span> multiplier)
  35.995 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">inverse-accumulation</span> divider)
  35.996 +<span style="color: #708070;">;;</span><span style="color: #7f9f7f;">left-circular-shift</span>
  35.997 +<span style="color: #708070;">;;</span><span style="color: #7f9f7f;">right-circular-shift</span>
  35.998 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">exactly-n?</span> same-endpoints?)
  35.999 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">any-number?</span> naturals?)
 35.1000 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">TODO compose</span>
 35.1001 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">TODO compose-n</span>
 35.1002 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">identity</span>
 35.1003 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">compose-2</span> fan-in)
 35.1004 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">compose-bin</span> fan-in*)
 35.1005 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">any?</span> (<span style="color: #8cd0d3;">constantly</span> true))
 35.1006 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">none?</span> (<span style="color: #8cd0d3;">constantly</span> false))
 35.1007 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">constant</span> constantly)
 35.1008 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">joint-arity</span> intersect)
 35.1009 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">a-reduce</span> reduce)
 35.1010 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">filter</span>
 35.1011 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">make-map</span> (<span style="color: #8cd0d3;">partial</span> partial map) )
 35.1012 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">bracket</span> juxt)
 35.1013 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">TODO apply-to-all</span>
 35.1014 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">TODO nary-combine</span>
 35.1015 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">TODO binary-combine</span>
 35.1016 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">TODO unary-combine</span>
 35.1017 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">iterated</span>
 35.1018 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">iterate-until-stable</span>
 35.1019 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">make-function-of-vector</span> (<span style="color: #8cd0d3;">partial</span> partial map))
 35.1020 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">make-function-of-arguments</span> (<span style="color: #8cd0d3;">fn</span> [f] (<span style="color: #8cd0d3;">fn</span> [&amp; args] (f args))))
 35.1021 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">alphaless</span> lexical&lt;)
 35.1022 +
 35.1023 +</pre>
 35.1024 +
 35.1025 +
 35.1026 +
 35.1027 +
 35.1028 +
 35.1029 +
 35.1030 +
 35.1031 +
 35.1032 +
 35.1033 +
 35.1034 +
 35.1035 +
 35.1036 +</div>
 35.1037 +</div>
 35.1038 +
 35.1039 +</div>
 35.1040 +
 35.1041 +<div id="outline-container-4" class="outline-2">
 35.1042 +<h2 id="sec-4"><span class="section-number-2">4</span> Numerical Methods </h2>
 35.1043 +<div class="outline-text-2" id="text-4">
 35.1044 +
 35.1045 +
 35.1046 +
 35.1047 +
 35.1048 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
 35.1049 +(<span style="color: #f0dfaf; font-weight: bold;">import</span> java.lang.Math)
 35.1050 +(<span style="color: #8cd0d3;">use</span> 'clojure.contrib.def)
 35.1051 +
 35.1052 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">---- USEFUL CONSTANTS</span>
 35.1053 +
 35.1054 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">machine-epsilon</span>
 35.1055 +  <span style="color: #8fb28f;">"Smallest value representable on your machine, as determined by</span>
 35.1056 +<span style="color: #8fb28f;">successively dividing a number in half until consecutive results are</span>
 35.1057 +<span style="color: #8fb28f;">indistinguishable."</span>
 35.1058 +  []
 35.1059 +  (<span style="color: #8cd0d3;">ffirst</span>
 35.1060 +   (<span style="color: #8cd0d3;">drop-while</span>
 35.1061 +    (<span style="color: #8cd0d3;">comp</span> not zero? second)
 35.1062 +    (<span style="color: #8cd0d3;">partition</span> 2 1
 35.1063 +               (<span style="color: #8cd0d3;">iterate</span> (<span style="color: #8cd0d3;">partial</span> * 0.5) 1)))))
 35.1064 +
 35.1065 +
 35.1066 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">pi</span> (Math/PI))
 35.1067 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">two-pi</span> (<span style="color: #8cd0d3;">*</span> 2 pi))
 35.1068 +
 35.1069 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">eulers-gamma</span> 0.5772156649015328606065)
 35.1070 +
 35.1071 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">phi</span> (<span style="color: #8cd0d3;">/</span> (<span style="color: #8cd0d3;">inc</span> (Math/sqrt 5)) 2))
 35.1072 +
 35.1073 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">ln2</span> (Math/log 2))
 35.1074 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">ln10</span> (Math/log 10))
 35.1075 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">exp10</span> #(Math/pow 10 %))
 35.1076 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">exp2</span> #(Math/pow 2 %))
 35.1077 +
 35.1078 +
 35.1079 +<span style="color: #708070;">;;</span>
 35.1080 +
 35.1081 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">---- ANGLES AND TRIGONOMETRY</span>
 35.1082 +
 35.1083 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">angle-restrictor</span>
 35.1084 +  <span style="color: #8fb28f;">"Returns a function that ensures that angles lie in the specified interval of length two-pi."</span>
 35.1085 +  [max-angle]
 35.1086 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [min-angle (<span style="color: #8cd0d3;">-</span> max-angle two-pi)]
 35.1087 +    (<span style="color: #8cd0d3;">fn</span> [x]
 35.1088 +      (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #f0dfaf; font-weight: bold;">and</span>
 35.1089 +           (<span style="color: #8cd0d3;">&lt;=</span> min-angle x)
 35.1090 +           (<span style="color: #8cd0d3;">&lt;</span> x max-angle))
 35.1091 +        x
 35.1092 +        (<span style="color: #f0dfaf; font-weight: bold;">let</span> [corrected-x (<span style="color: #8cd0d3;">-</span> x (<span style="color: #8cd0d3;">*</span> two-pi (Math/floor (<span style="color: #8cd0d3;">/</span> x two-pi))))]
 35.1093 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">&lt;</span> corrected-x max-angle)
 35.1094 +            corrected-x
 35.1095 +            (<span style="color: #8cd0d3;">-</span> corrected-x two-pi)))))))
 35.1096 +
 35.1097 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">angle-restrict-pi</span>
 35.1098 +  <span style="color: #8fb28f;">"Coerces angles to lie in the interval from -pi to pi."</span>
 35.1099 +  [angle]
 35.1100 +  ((angle-restrictor pi) angle))
 35.1101 +
 35.1102 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">angle-restrict-two-pi</span>
 35.1103 +  <span style="color: #8fb28f;">"Coerces angles to lie in the interval from zero to two-pi"</span>
 35.1104 +  [angle]
 35.1105 +  ((angle-restrictor two-pi) angle))
 35.1106 +
 35.1107 +
 35.1108 +
 35.1109 +
 35.1110 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">invert</span> [x] (<span style="color: #8cd0d3;">/</span> x))
 35.1111 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">negate</span> [x] (<span style="color: #8cd0d3;">-</span> x))
 35.1112 +
 35.1113 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">exp</span> [x] (Math/exp x))
 35.1114 +
 35.1115 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">sin</span> [x] (Math/sin x))
 35.1116 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">cos</span> [x] (Math/cos x))
 35.1117 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">tan</span> [x] (Math/tan x))
 35.1118 +
 35.1119 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">sec</span> (<span style="color: #8cd0d3;">comp</span> invert cos))
 35.1120 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">csc</span> (<span style="color: #8cd0d3;">comp</span> invert sin))
 35.1121 +
 35.1122 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">sinh</span> [x] (Math/sinh x))
 35.1123 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">cosh</span> [x] (Math/cosh x))
 35.1124 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">tanh</span> [x] (Math/tanh x))
 35.1125 +
 35.1126 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">sech</span> (<span style="color: #8cd0d3;">comp</span> invert cosh))
 35.1127 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">csch</span> (<span style="color: #8cd0d3;">comp</span> invert sinh))
 35.1128 +
 35.1129 +
 35.1130 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">------------</span>
 35.1131 +
 35.1132 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">factorial</span>
 35.1133 +  <span style="color: #8fb28f;">"Computes the factorial of the nonnegative integer n."</span>
 35.1134 +  [n]
 35.1135 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">neg?</span> n)
 35.1136 +    (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"Cannot compute the factorial of a negative number."</span>))
 35.1137 +    (<span style="color: #8cd0d3;">reduce</span> * 1 (<span style="color: #8cd0d3;">range</span> 1 (<span style="color: #8cd0d3;">inc</span> n)))))
 35.1138 +
 35.1139 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">exact-quotient</span> [n d] (<span style="color: #8cd0d3;">/</span> n d))
 35.1140 +
 35.1141 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">binomial-coefficient</span>
 35.1142 +  <span style="color: #8fb28f;">"Computes the number of different ways to choose m elements from n."</span>
 35.1143 +  [n m]
 35.1144 +  (<span style="color: #8cd0d3;">assert</span> (<span style="color: #8cd0d3;">&lt;=</span> 0 m n))
 35.1145 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [difference (<span style="color: #8cd0d3;">-</span> n m)]
 35.1146 +    (exact-quotient
 35.1147 +     (<span style="color: #8cd0d3;">reduce</span> * (<span style="color: #8cd0d3;">range</span> n (<span style="color: #8cd0d3;">max</span> difference m) -1 ))
 35.1148 +     (factorial (<span style="color: #8cd0d3;">min</span> difference m)))))
 35.1149 +
 35.1150 +(<span style="color: #f0dfaf; font-weight: bold;">defn-memo</span> <span style="color: #f0dfaf;">stirling-1</span>
 35.1151 +  <span style="color: #cc9393;">"Stirling numbers of the first kind: the number of permutations of n</span>
 35.1152 +<span style="color: #cc9393;">  elements with exactly m permutation cycles. "</span>
 35.1153 +  [n k]
 35.1154 +  <span style="color: #708070;">;</span><span style="color: #7f9f7f;">(assert (&lt;= 1 k n))</span>
 35.1155 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? n)
 35.1156 +    (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? k) 1 0)
 35.1157 +    (<span style="color: #8cd0d3;">+</span> (stirling-1 (<span style="color: #8cd0d3;">dec</span> n) (<span style="color: #8cd0d3;">dec</span> k))
 35.1158 +       (<span style="color: #8cd0d3;">*</span> (<span style="color: #8cd0d3;">dec</span> n) (stirling-1 (<span style="color: #8cd0d3;">dec</span> n) k)))))
 35.1159 +
 35.1160 +(<span style="color: #f0dfaf; font-weight: bold;">defn-memo</span> <span style="color: #f0dfaf;">stirling-2</span> <span style="color: #708070;">;;</span><span style="color: #7f9f7f;">count-partitions</span>
 35.1161 +  <span style="color: #cc9393;">"Stirling numbers of the second kind: the number of ways to partition a set of n elements into k subsets."</span>
 35.1162 +  [n k]
 35.1163 +  (<span style="color: #f0dfaf; font-weight: bold;">cond</span>
 35.1164 +   (<span style="color: #8cd0d3;">=</span> k 1) 1
 35.1165 +   (<span style="color: #8cd0d3;">=</span> k n) 1
 35.1166 +   <span style="color: #8cd0d3;">:else</span> (<span style="color: #8cd0d3;">+</span> (stirling-2 (<span style="color: #8cd0d3;">dec</span> n) (<span style="color: #8cd0d3;">dec</span> k))
 35.1167 +            (<span style="color: #8cd0d3;">*</span> k (stirling-2 (<span style="color: #8cd0d3;">dec</span> n) k)))))
 35.1168 +
 35.1169 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">harmonic-number</span> [n]
 35.1170 +  (<span style="color: #8cd0d3;">/</span> (stirling-1 (<span style="color: #8cd0d3;">inc</span> n) 2)
 35.1171 +     (factorial n)))
 35.1172 +
 35.1173 +
 35.1174 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">sum</span>
 35.1175 +  [f low high]
 35.1176 +  (<span style="color: #8cd0d3;">reduce</span> + (<span style="color: #8cd0d3;">map</span> f (<span style="color: #8cd0d3;">range</span> low (<span style="color: #8cd0d3;">inc</span> high)))))
 35.1177 +
 35.1178 +</pre>
 35.1179 +
 35.1180 +
 35.1181 +
 35.1182 +
 35.1183 +
 35.1184 +
 35.1185 +
 35.1186 +
 35.1187 +
 35.1188 +
 35.1189 +
 35.1190 +
 35.1191 +
 35.1192 +
 35.1193 +
 35.1194 +</div>
 35.1195 +
 35.1196 +</div>
 35.1197 +
 35.1198 +<div id="outline-container-5" class="outline-2">
 35.1199 +<h2 id="sec-5"><span class="section-number-2">5</span> Differentiation </h2>
 35.1200 +<div class="outline-text-2" id="text-5">
 35.1201 +
 35.1202 +
 35.1203 +<p>
 35.1204 +We compute derivatives by passing special <b>differential objects</b> \([x,
 35.1205 +dx]\) through functions. Roughly speaking, applying a function \(f\) to a
 35.1206 +differential object \([x, dx]\) should produce a new differential
 35.1207 +object \([f(x),\,Df(x)\cdot dx]\).
 35.1208 +</p>
 35.1209 +
 35.1210 +
 35.1211 +\([x,\,dx]\xrightarrow{\quad f \quad}[f(x),\,Df(x)\cdot dx]\)
 35.1212 +<p>
 35.1213 +Notice that you can obtain the derivative of \(f\) from this
 35.1214 +differential object, as it is the coefficient of the \(dx\) term. Also,
 35.1215 +as you apply successive functions using this rule, you get the
 35.1216 +chain-rule answer you expect:
 35.1217 +</p>
 35.1218 +
 35.1219 +
 35.1220 +\([f(x),\,Df(x)\cdot dx]\xrightarrow{\quad g\quad} [gf(x),\,
 35.1221 +Dgf(x)\cdot Df(x) \cdot dx ]\)
 35.1222 +
 35.1223 +<p>
 35.1224 +In order to generalize to multiple variables and multiple derivatives,
 35.1225 +we use a <b>power series of differentials</b>, a sortred infinite sequence which
 35.1226 +contains all terms like \(dx\cdot dy\), \(dx^2\cdot dy\), etc.
 35.1227 +</p>
 35.1228 +
 35.1229 +
 35.1230 +
 35.1231 +
 35.1232 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
 35.1233 +
 35.1234 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-seq</span>
 35.1235 +  <span style="color: #8fb28f;">"Constructs a sequence of differential terms from a numerical</span>
 35.1236 +<span style="color: #8fb28f;">coefficient and a list of keys for variables. If no coefficient is supplied, uses 1."</span>
 35.1237 +  ([variables] (differential-seq* 1 variables))
 35.1238 +  ([coefficient variables &amp; cvs]
 35.1239 +     (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">number?</span> coefficient)
 35.1240 +       (<span style="color: #8cd0d3;">conj</span> (<span style="color: #8cd0d3;">assoc</span> {} (<span style="color: #8cd0d3;">apply</span> sorted-set variables) coefficient)
 35.1241 +             (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">empty?</span> cvs)
 35.1242 +               nil
 35.1243 +               (<span style="color: #8cd0d3;">apply</span> differential-seq* cvs)))
 35.1244 +       (<span style="color: #8cd0d3;">apply</span> differential-seq* 1 coefficient 1 variables cvs)  
 35.1245 +       )))
 35.1246 +
 35.1247 +
 35.1248 +
 35.1249 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-add</span>
 35.1250 +  <span style="color: #8fb28f;">"Add two differential sequences by combining like terms."</span>
 35.1251 +  [dseq1 dseq2]
 35.1252 +  (<span style="color: #8cd0d3;">merge-with</span> + dseq1 dseq2))
 35.1253 +
 35.1254 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-multiply</span>
 35.1255 +  <span style="color: #8fb28f;">"Multiply two differential sequences. The square of any differential variable is zero since differential variables are infinitesimally small."</span>
 35.1256 +  [dseq1 dseq2]
 35.1257 +  (<span style="color: #8cd0d3;">reduce</span>
 35.1258 +   (<span style="color: #8cd0d3;">fn</span> [m [[vars1 coeff1] [vars2 coeff2]]]
 35.1259 +     (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">empty?</span> (clojure.set/<span style="color: #dfdfbf; font-weight: bold;">intersection</span> vars1 vars2))
 35.1260 +       (<span style="color: #8cd0d3;">assoc</span> m (clojure.set/<span style="color: #dfdfbf; font-weight: bold;">union</span> vars1 vars2) (<span style="color: #8cd0d3;">*</span> coeff1 coeff2))
 35.1261 +       m))
 35.1262 +   {}
 35.1263 +  (clojure.contrib.combinatorics/cartesian-product
 35.1264 +   dseq1
 35.1265 +   dseq2)))
 35.1266 +
 35.1267 +
 35.1268 +
 35.1269 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">big-part</span>
 35.1270 +  <span style="color: #8fb28f;">"Returns the 'finite' part of the differential sequence."</span>
 35.1271 +  [dseq]
 35.1272 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span>
 35.1273 +      [keys (<span style="color: #8cd0d3;">sort-by</span> count (<span style="color: #8cd0d3;">keys</span> dseq))
 35.1274 +       pivot-key (<span style="color: #8cd0d3;">first</span> (<span style="color: #8cd0d3;">last</span> keys))]
 35.1275 +
 35.1276 +    (<span style="color: #8cd0d3;">apply</span> hash-map
 35.1277 +    (<span style="color: #8cd0d3;">reduce</span> concat
 35.1278 +            (<span style="color: #8cd0d3;">filter</span> (<span style="color: #8cd0d3;">comp</span> pivot-key first) dseq)
 35.1279 +            ))))
 35.1280 +
 35.1281 +
 35.1282 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">small-part</span>
 35.1283 +  <span style="color: #8fb28f;">"Returns the 'infinitesimal' part of the differential sequence."</span>
 35.1284 +  [dseq]
 35.1285 +    (<span style="color: #f0dfaf; font-weight: bold;">let</span>
 35.1286 +      [keys (<span style="color: #8cd0d3;">sort-by</span> count (<span style="color: #8cd0d3;">keys</span> dseq))
 35.1287 +       pivot-key (<span style="color: #8cd0d3;">first</span> (<span style="color: #8cd0d3;">last</span> keys))]
 35.1288 +
 35.1289 +    (<span style="color: #8cd0d3;">apply</span> hash-map
 35.1290 +    (<span style="color: #8cd0d3;">reduce</span> concat
 35.1291 +            (<span style="color: #8cd0d3;">remove</span> (<span style="color: #8cd0d3;">comp</span> pivot-key first) dseq)
 35.1292 +            ))))
 35.1293 +
 35.1294 +
 35.1295 +
 35.1296 +
 35.1297 +
 35.1298 +
 35.1299 +
 35.1300 +
 35.1301 +
 35.1302 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">;; A differential term consists of a numerical coefficient and a</span>
 35.1303 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">;; sorted  </span>
 35.1304 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">(defrecord DifferentialTerm [coefficient variables])</span>
 35.1305 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">(defmethod print-method DifferentialTerm</span>
 35.1306 +<span style="color: #708070;">;;    </span><span style="color: #7f9f7f;">[o w]</span>
 35.1307 +<span style="color: #708070;">;;     </span><span style="color: #7f9f7f;">(print-simple</span>
 35.1308 +<span style="color: #708070;">;;      </span><span style="color: #7f9f7f;">(apply str (.coefficient o)(map (comp (partial str "d") name) (.variables o)))</span>
 35.1309 +<span style="color: #708070;">;;      </span><span style="color: #7f9f7f;">w))</span>
 35.1310 +
 35.1311 +
 35.1312 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">(defn differential-seq</span>
 35.1313 +<span style="color: #708070;">;;   </span><span style="color: #7f9f7f;">"Constructs a sequence of differential terms from a numerical</span>
 35.1314 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">coefficient and a list of keywords for variables. If no coefficient is</span>
 35.1315 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">supplied, uses 1."</span>
 35.1316 +<span style="color: #708070;">;;   </span><span style="color: #7f9f7f;">([variables] (differential-seq 1 variables))</span>
 35.1317 +<span style="color: #708070;">;;   </span><span style="color: #7f9f7f;">([coefficient variables]</span>
 35.1318 +<span style="color: #708070;">;;      </span><span style="color: #7f9f7f;">(list</span>
 35.1319 +<span style="color: #708070;">;;       </span><span style="color: #7f9f7f;">(DifferentialTerm. coefficient (apply sorted-set variables))))</span>
 35.1320 +<span style="color: #708070;">;;   </span><span style="color: #7f9f7f;">([coefficient variables &amp; cvs]</span>
 35.1321 +<span style="color: #708070;">;;      </span><span style="color: #7f9f7f;">(sort-by</span>
 35.1322 +<span style="color: #708070;">;;       </span><span style="color: #7f9f7f;">#(vec(.variables %))</span>
 35.1323 +<span style="color: #708070;">;;       </span><span style="color: #7f9f7f;">(concat (differential-seq coefficient variables) (apply differential-seq cvs)))))</span>
 35.1324 +
 35.1325 +</pre>
 35.1326 +
 35.1327 +
 35.1328 +
 35.1329 +
 35.1330 +
 35.1331 +
 35.1332 +
 35.1333 +
 35.1334 +
 35.1335 +
 35.1336 +
 35.1337 +
 35.1338 +
 35.1339 +
 35.1340 +
 35.1341 +
 35.1342 +</div>
 35.1343 +
 35.1344 +</div>
 35.1345 +
 35.1346 +<div id="outline-container-6" class="outline-2">
 35.1347 +<h2 id="sec-6"><span class="section-number-2">6</span> Symbolic Manipulation </h2>
 35.1348 +<div class="outline-text-2" id="text-6">
 35.1349 +
 35.1350 +
 35.1351 +
 35.1352 +
 35.1353 +
 35.1354 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
 35.1355 +
 35.1356 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">Symbolic</span> [type expression]
 35.1357 +  Object
 35.1358 +  (equals [this that]
 35.1359 +          (<span style="color: #f0dfaf; font-weight: bold;">cond</span>
 35.1360 +           (<span style="color: #8cd0d3;">=</span> (.expression this) (.expression that)) true
 35.1361 +           <span style="color: #8cd0d3;">:else</span>
 35.1362 +           (Symbolic.
 35.1363 +            java.lang.Boolean
 35.1364 +            (<span style="color: #8cd0d3;">list</span> '= (.expression this) (.expression that)))
 35.1365 +          )))
 35.1366 +
 35.1367 +
 35.1368 +
 35.1369 +
 35.1370 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">AbstractSet</span> [glyph membership-test])
 35.1371 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">member?</span> [abstract-set x]
 35.1372 +  ((.membership-test abstract-set) x))
 35.1373 +
 35.1374 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">------------ Some important AbstractSets</span>
 35.1375 +
 35.1376 +
 35.1377 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">Real</span>
 35.1378 +     (AbstractSet.
 35.1379 +      'R
 35.1380 +      (<span style="color: #8cd0d3;">fn</span>[x](<span style="color: #8cd0d3;">number?</span> x))))
 35.1381 +
 35.1382 +
 35.1383 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">------------ Create new AbstractSets from existing ones</span>
 35.1384 +
 35.1385 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">abstract-product</span>
 35.1386 +  <span style="color: #8fb28f;">"Gives the cartesian product of abstract sets."</span>
 35.1387 +  ([sets]
 35.1388 +       (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">count</span> sets) 1) (<span style="color: #8cd0d3;">first</span> sets)
 35.1389 +           (AbstractSet.
 35.1390 +            (<span style="color: #8cd0d3;">symbol</span>
 35.1391 +             (<span style="color: #8cd0d3;">apply</span> str
 35.1392 +                    (<span style="color: #8cd0d3;">interpose</span> 'x (<span style="color: #8cd0d3;">map</span> #(.glyph %) sets))))
 35.1393 +           (<span style="color: #8cd0d3;">fn</span> [x]
 35.1394 +             (<span style="color: #f0dfaf; font-weight: bold;">and</span>
 35.1395 +              (<span style="color: #8cd0d3;">coll?</span> x)
 35.1396 +              (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">count</span> sets) (<span style="color: #8cd0d3;">count</span> x))
 35.1397 +              (<span style="color: #8cd0d3;">reduce</span> #(<span style="color: #f0dfaf; font-weight: bold;">and</span> %1 %2)
 35.1398 +                      true
 35.1399 +                      (<span style="color: #8cd0d3;">map</span> #(member? %1 %2) sets x)))))))
 35.1400 +  ([abstract-set n]
 35.1401 +     (abstract-product (<span style="color: #8cd0d3;">repeat</span> n abstract-set))))
 35.1402 +
 35.1403 +
 35.1404 +              
 35.1405 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">abstract-up</span>
 35.1406 +  <span style="color: #8fb28f;">"Returns the abstract set of all up-tuples whose items belong to the</span>
 35.1407 +<span style="color: #8fb28f;">  corresponding abstract sets in coll."</span>
 35.1408 +  ([coll]
 35.1409 +     (AbstractSet.
 35.1410 +      (<span style="color: #8cd0d3;">symbol</span> (<span style="color: #8cd0d3;">str</span> <span style="color: #cc9393;">"u["</span>
 35.1411 +                   (<span style="color: #8cd0d3;">apply</span> str
 35.1412 +                          (<span style="color: #8cd0d3;">interpose</span> <span style="color: #cc9393;">" "</span>
 35.1413 +                                     (<span style="color: #8cd0d3;">map</span> #(.glyph %) coll)))
 35.1414 +                   <span style="color: #cc9393;">"]"</span>))
 35.1415 +      (<span style="color: #8cd0d3;">fn</span> [x]
 35.1416 +        (<span style="color: #f0dfaf; font-weight: bold;">and</span>
 35.1417 +         (<span style="color: #8cd0d3;">satisfies?</span> Spinning x)
 35.1418 +         (up? x)
 35.1419 +         (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">count</span> coll) (<span style="color: #8cd0d3;">count</span> x))
 35.1420 +         (<span style="color: #8cd0d3;">reduce</span>
 35.1421 +          #(<span style="color: #f0dfaf; font-weight: bold;">and</span> %1 %2)
 35.1422 +          true
 35.1423 +          (<span style="color: #8cd0d3;">map</span> #(member? %1 %2) coll x))))))
 35.1424 +  ([abstract-set n]
 35.1425 +     (abstract-up (<span style="color: #8cd0d3;">repeat</span> n abstract-set))))
 35.1426 +
 35.1427 +
 35.1428 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">abstract-down</span>
 35.1429 +  <span style="color: #8fb28f;">"Returns the abstract set of all down-tuples whose items belong to the</span>
 35.1430 +<span style="color: #8fb28f;">  corresponding abstract sets in coll."</span>
 35.1431 +  ([coll]
 35.1432 +     (AbstractSet.
 35.1433 +      (<span style="color: #8cd0d3;">symbol</span> (<span style="color: #8cd0d3;">str</span> <span style="color: #cc9393;">"d["</span>
 35.1434 +                   (<span style="color: #8cd0d3;">apply</span> str
 35.1435 +                          (<span style="color: #8cd0d3;">interpose</span> <span style="color: #cc9393;">" "</span>
 35.1436 +                                     (<span style="color: #8cd0d3;">map</span> #(.glyph %) coll)))
 35.1437 +                   <span style="color: #cc9393;">"]"</span>))
 35.1438 +      (<span style="color: #8cd0d3;">fn</span> [x]
 35.1439 +        (<span style="color: #f0dfaf; font-weight: bold;">and</span>
 35.1440 +         (<span style="color: #8cd0d3;">satisfies?</span> Spinning x)
 35.1441 +         (down? x)
 35.1442 +         (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">count</span> coll) (<span style="color: #8cd0d3;">count</span> x))
 35.1443 +         (<span style="color: #8cd0d3;">reduce</span>
 35.1444 +          #(<span style="color: #f0dfaf; font-weight: bold;">and</span> %1 %2)
 35.1445 +          true
 35.1446 +          (<span style="color: #8cd0d3;">map</span> #(member? %1 %2) coll x))))))
 35.1447 +  ([abstract-set n]
 35.1448 +     (abstract-down (<span style="color: #8cd0d3;">repeat</span> n abstract-set))))
 35.1449 +
 35.1450 +              
 35.1451 +
 35.1452 +
 35.1453 +
 35.1454 +                                        <span style="color: #708070;">;</span><span style="color: #7f9f7f;">-------ABSTRACT FUNCTIONS</span>
 35.1455 +(<span style="color: #f0dfaf; font-weight: bold;">defrecord</span> <span style="color: #f0dfaf;">AbstractFn</span>
 35.1456 +  [<span style="color: #dfdfbf; font-weight: bold;">#^AbstractSet</span> domain <span style="color: #dfdfbf; font-weight: bold;">#^AbstractSet</span> codomain])
 35.1457 +
 35.1458 +
 35.1459 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">print-method</span> AbstractFn
 35.1460 +  [o w]
 35.1461 +  (<span style="color: #8cd0d3;">print-simple</span>
 35.1462 +   (<span style="color: #8cd0d3;">str</span>
 35.1463 +    <span style="color: #cc9393;">"f:"</span>
 35.1464 +   (.glyph (<span style="color: #8cd0d3;">:domain</span> o))
 35.1465 +   <span style="color: #cc9393;">"--&gt;"</span>
 35.1466 +   (.glyph (<span style="color: #8cd0d3;">:codomain</span> o))) w))
 35.1467 +</pre>
 35.1468 +
 35.1469 +
 35.1470 +
 35.1471 +
 35.1472 +
 35.1473 +
 35.1474 +
 35.1475 +</div>
 35.1476 +</div>
 35.1477 +<div id="postamble">
 35.1478 +<p class="date">Date: 2011-08-09 18:41:37 EDT</p>
 35.1479 +<p class="author">Author: Robert McIntyre & Dylan Holmes</p>
 35.1480 +<p class="creator">Org version 7.6 with Emacs version 23</p>
 35.1481 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
 35.1482 +</div>
 35.1483 +</div>
 35.1484 +</body>
 35.1485 +</html>
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/sicm/bk/utils.org	Fri Oct 28 00:03:05 2011 -0700
    36.3 @@ -0,0 +1,1262 @@
    36.4 +#+TITLE:Building a Classical Mechanics Library in Clojure
    36.5 +#+author: Robert McIntyre & Dylan Holmes
    36.6 +#+EMAIL:     rlm@mit.edu
    36.7 +#+MATHJAX: align:"left" mathml:t path:"../MathJax/MathJax.js"
    36.8 +#+STYLE: <link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
    36.9 +#+OPTIONS:   H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
   36.10 +#+SETUPFILE: ../templates/level-0.org
   36.11 +#+INCLUDE: ../templates/level-0.org
   36.12 +#+BABEL: :noweb yes :results silent
   36.13 +
   36.14 +* Generic Arithmetic
   36.15 +
   36.16 +#+srcname: generic-arithmetic
   36.17 +#+begin_src clojure
   36.18 +(ns sicm.utils)
   36.19 +(in-ns 'sicm.utils)
   36.20 +
   36.21 +
   36.22 +
   36.23 +(defn all-equal? [coll]
   36.24 +  (if (empty? (rest coll)) true
   36.25 +      (and (= (first coll) (second coll))
   36.26 +	   (recur (rest coll)))))
   36.27 +
   36.28 +
   36.29 +(defprotocol Arithmetic
   36.30 +  (zero [this])
   36.31 +  (one [this])
   36.32 +  (negate [this])
   36.33 +  (invert [this])
   36.34 +  (conjugate [this]))
   36.35 +
   36.36 +(defn zero? [x]
   36.37 +  (= x (zero x)))
   36.38 +(defn one? [x]
   36.39 +  (= x (one x)))
   36.40 +
   36.41 +
   36.42 +
   36.43 +(extend-protocol Arithmetic
   36.44 +  java.lang.Number
   36.45 +  (zero [x] 0)
   36.46 +  (one [x] 1)
   36.47 +  (negate [x] (- x))
   36.48 +  (invert [x] (/ x))
   36.49 +  )
   36.50 +
   36.51 +(extend-protocol Arithmetic
   36.52 +  clojure.lang.IFn
   36.53 +  (one [f] identity)
   36.54 +  (negate [f] (comp negate f))
   36.55 +  (invert [f] (comp invert f)))
   36.56 +
   36.57 +    
   36.58 +(extend-protocol Arithmetic
   36.59 +  clojure.lang.Seqable
   36.60 +  (zero [this] (map zero this))
   36.61 +  (one [this] (map one this))
   36.62 +  (invert [this] (map invert this))
   36.63 +  (negate [this] (map negate this)))
   36.64 +
   36.65 +
   36.66 +(defn ordered-like
   36.67 +  "Create a comparator using the sorted collection as an
   36.68 +  example. Elements not in the sorted collection are sorted to the
   36.69 +  end."
   36.70 +  [sorted-coll]
   36.71 +  (let [
   36.72 +	sorted-coll? (set sorted-coll) 
   36.73 +	ascending-pair?
   36.74 +	(set(reduce concat
   36.75 +		    (map-indexed
   36.76 +		     (fn [n x]
   36.77 +		       (map #(vector x %) (nthnext sorted-coll n)))
   36.78 +		     sorted-coll)))]
   36.79 +    (fn [x y]
   36.80 +      (cond
   36.81 +       (= x y) 0
   36.82 +       (ascending-pair? [x y]) -1
   36.83 +       (ascending-pair? [y x]) 1
   36.84 +       (sorted-coll? x) -1
   36.85 +       (sorted-coll? y) 1))))
   36.86 +  
   36.87 +
   36.88 +
   36.89 +(def type-precedence
   36.90 +  (ordered-like [incanter.Matrix]))
   36.91 +
   36.92 +(defmulti add
   36.93 +    (fn [x y]
   36.94 +      (sort type-precedence [(type x)(type y)]))) 
   36.95 +
   36.96 +(defmulti multiply
   36.97 +  (fn [x y]
   36.98 +    (sort type-precedence [(type x) (type y)])))
   36.99 +
  36.100 +(defmethod add [java.lang.Number java.lang.Number] [x y] (+ x y))
  36.101 +(defmethod multiply [java.lang.Number java.lang.Number] [x y] (* x y))
  36.102 +
  36.103 +(defmethod multiply [incanter.Matrix java.lang.Integer] [x y]
  36.104 +	   (let [args (sort #(type-precedence (type %1)(type %2)) [x y])
  36.105 +		 matrix (first args)
  36.106 +		 scalar (second args)]
  36.107 +	     (incanter.core/matrix (map (partial map (partial multiply scalar)) matrix))))
  36.108 +	   
  36.109 +#+end_src
  36.110 +
  36.111 +
  36.112 +* Useful Data Types
  36.113 +
  36.114 +** Complex Numbers
  36.115 +#+srcname: complex-numbers
  36.116 +#+begin_src clojure
  36.117 +(in-ns 'sicm.utils)
  36.118 +
  36.119 +(defprotocol Complex
  36.120 +  (real-part [z])
  36.121 +  (imaginary-part [z])
  36.122 +  (magnitude-squared [z])
  36.123 +  (angle [z])
  36.124 +  (conjugate [z])
  36.125 +  (norm [z]))
  36.126 +
  36.127 +(defn complex-rectangular
  36.128 +  "Define a complex number with the given real and imaginary
  36.129 +  components."
  36.130 +  [re im]
  36.131 +  (reify Complex
  36.132 +	 (real-part [z] re)
  36.133 +	 (imaginary-part [z] im)
  36.134 +	 (magnitude-squared [z] (+ (* re re) (* im im)))
  36.135 +	 (angle [z] (java.lang.Math/atan2 im re))
  36.136 +	 (conjugate [z] (complex-rectangular re (- im)))
  36.137 +
  36.138 +	 Arithmetic
  36.139 +	 (zero [z] (complex-rectangular 0 0))
  36.140 +	 (one [z] (complex-rectangular 1 0))
  36.141 +	 (negate [z] (complex-rectangular (- re) (- im)))
  36.142 +	 (invert [z] (complex-rectangular
  36.143 +		      (/ re (magnitude-squared z))
  36.144 +		      (/ (- im) (magnitude-squared z))))
  36.145 +
  36.146 +	 Object
  36.147 +	 (toString [_]
  36.148 +		   (if (and (zero? re) (zero? im)) (str 0)
  36.149 +		       (str
  36.150 +			(if (not(zero? re))
  36.151 +			  re)
  36.152 +			(if ((comp not zero?) im)
  36.153 +			  (str
  36.154 +			   (if (neg? im) "-" "+")
  36.155 +			   (if ((comp not one?) (java.lang.Math/abs im))
  36.156 +			   (java.lang.Math/abs im))
  36.157 +			   "i")))))))
  36.158 +
  36.159 +(defn complex-polar
  36.160 +  "Define a complex number with the given magnitude and angle."
  36.161 +  [mag ang]
  36.162 +  (reify Complex
  36.163 +	 (magnitude-squared [z] (* mag mag))
  36.164 +	 (angle [z] angle)
  36.165 +	 (real-part [z] (* mag (java.lang.Math/cos ang)))
  36.166 +	 (imaginary-part [z] (* mag (java.lang.Math/sin ang)))
  36.167 +	 (conjugate [z] (complex-polar mag (- ang)))
  36.168 +
  36.169 +	 Arithmetic
  36.170 +	 (zero [z] (complex-polar 0 0))
  36.171 +	 (one [z] (complex-polar 1 0))
  36.172 +	 (negate [z] (complex-polar (- mag) ang))
  36.173 +	 (invert [z] (complex-polar (/ mag) (- ang)))
  36.174 +
  36.175 +	 Object
  36.176 +	 (toString [_] (str mag " * e^(i" ang")"))
  36.177 +	 ))
  36.178 +
  36.179 +
  36.180 +;; Numbers are complex quantities
  36.181 +
  36.182 +(extend-protocol Complex
  36.183 +  java.lang.Number
  36.184 +  (real-part [x] x)
  36.185 +  (imaginary-part [x] 0)
  36.186 +  (magnitude [x] x)
  36.187 +  (angle [x] 0)
  36.188 +  (conjugate [x] x))
  36.189 +
  36.190 +
  36.191 +#+end_src
  36.192 +
  36.193 +
  36.194 +
  36.195 +** Tuples and Tensors
  36.196 +
  36.197 +A tuple is a vector which is spinable\mdash{}it can be either /spin
  36.198 +up/ or /spin down/. (Covariant, contravariant; dual vectors)
  36.199 +#+srcname: tuples
  36.200 +#+begin_src clojure
  36.201 +(in-ns 'sicm.utils)
  36.202 +
  36.203 +(defprotocol Spinning
  36.204 +  (up? [this])
  36.205 +  (down? [this]))
  36.206 +
  36.207 +(defn spin
  36.208 +  "Returns the spin of the Spinning s, either :up or :down"
  36.209 +  [#^Spinning s]
  36.210 +  (cond (up? s) :up (down? s) :down))
  36.211 +
  36.212 +
  36.213 +(deftype Tuple
  36.214 +  [spin coll]
  36.215 +  clojure.lang.Seqable
  36.216 +  (seq [this] (seq (.coll this)))
  36.217 +  clojure.lang.Counted
  36.218 +  (count [this] (count (.coll this))))
  36.219 +
  36.220 +(extend-type Tuple
  36.221 +  Spinning
  36.222 +  (up? [this] (= ::up (.spin this)))
  36.223 +  (down? [this] (= ::down (.spin this))))
  36.224 +
  36.225 +(defmethod print-method Tuple
  36.226 +  [o w]
  36.227 +  (print-simple (str (if (up? o) 'u 'd) (.coll o))  w))
  36.228 +
  36.229 +
  36.230 +
  36.231 +(defn up
  36.232 +  "Create a new up-tuple containing the contents of coll."
  36.233 +  [coll]
  36.234 +  (Tuple. ::up coll))       
  36.235 +
  36.236 +(defn down
  36.237 +  "Create a new down-tuple containing the contents of coll."
  36.238 +  [coll]
  36.239 +  (Tuple. ::down coll))
  36.240 +
  36.241 +
  36.242 +#+end_src
  36.243 +
  36.244 +*** Contraction
  36.245 +Contraction is a binary operation that you can apply to compatible
  36.246 + tuples. Tuples are compatible for contraction if they have the same
  36.247 + length and opposite spins, and if the corresponding items in each
  36.248 + tuple are both numbers or both compatible tuples.
  36.249 +
  36.250 +#+srcname: tuples-2
  36.251 +#+begin_src clojure
  36.252 +(in-ns 'sicm.utils)
  36.253 +
  36.254 +(defn numbers?
  36.255 +  "Returns true if all arguments are numbers, else false."
  36.256 +  [& xs]
  36.257 +  (every? number? xs))
  36.258 +
  36.259 +(defn contractible?
  36.260 +  "Returns true if the tuples a and b are compatible for contraction,
  36.261 +  else false. Tuples are compatible if they have the same number of
  36.262 +  components, they have opposite spins, and their elements are
  36.263 +  pairwise-compatible."
  36.264 +  [a b]
  36.265 +  (and
  36.266 +   (isa? (type a) Tuple)
  36.267 +   (isa? (type b) Tuple)
  36.268 +   (= (count a) (count b))
  36.269 +   (not= (spin a) (spin b))
  36.270 +   
  36.271 +   (not-any? false?
  36.272 +	     (map #(or
  36.273 +		    (numbers? %1 %2)
  36.274 +		    (contractible? %1 %2))
  36.275 +		  a b))))
  36.276 +
  36.277 +
  36.278 +
  36.279 +(defn contract
  36.280 +  "Contracts two tuples, returning the sum of the
  36.281 +  products of the corresponding items. Contraction is recursive on
  36.282 +  nested tuples."
  36.283 +  [a b]
  36.284 +  (if (not (contractible? a b))
  36.285 +    (throw
  36.286 +     (Exception. "Not compatible for contraction."))
  36.287 +    (reduce +
  36.288 +	    (map
  36.289 +	     (fn [x y]
  36.290 +	       (if (numbers? x y)
  36.291 +		 (* x y)
  36.292 +		 (contract x y)))
  36.293 +	     a b))))
  36.294 +
  36.295 +#+end_src
  36.296 +
  36.297 +*** Matrices
  36.298 +#+srcname: matrices
  36.299 +#+begin_src clojure
  36.300 +(in-ns 'sicm.utils)
  36.301 +(require 'incanter.core) ;; use incanter's fast matrices
  36.302 +
  36.303 +(defprotocol Matrix
  36.304 +  (rows [matrix])
  36.305 +  (cols [matrix])
  36.306 +  (diagonal [matrix])
  36.307 +  (trace [matrix])
  36.308 +  (determinant [matrix])
  36.309 +  (transpose [matrix])
  36.310 +  (conjugate [matrix])
  36.311 +)
  36.312 +
  36.313 +(extend-protocol Matrix
  36.314 +  incanter.Matrix
  36.315 +  (rows [rs] (map down (apply map vector (apply map vector rs))))
  36.316 +  (cols [rs] (map up (apply map vector rs)))
  36.317 +  (diagonal [matrix] (incanter.core/diag matrix) )
  36.318 +  (determinant [matrix] (incanter.core/det matrix))
  36.319 +  (trace [matrix] (incanter.core/trace matrix))
  36.320 +  (transpose [matrix] (incanter.core/trans matrix))
  36.321 +  )
  36.322 +
  36.323 +(defn count-rows [matrix]
  36.324 +  ((comp count rows) matrix))
  36.325 +
  36.326 +(defn count-cols [matrix]
  36.327 +  ((comp count cols) matrix))
  36.328 +
  36.329 +(defn square? [matrix]
  36.330 +  (= (count-rows matrix) (count-cols matrix)))
  36.331 +
  36.332 +(defn identity-matrix
  36.333 +  "Define a square matrix of size n-by-n with 1s along the diagonal and
  36.334 +  0s everywhere else."
  36.335 +  [n]
  36.336 +  (incanter.core/identity-matrix n))
  36.337 +
  36.338 +
  36.339 +
  36.340 +
  36.341 +
  36.342 +(defn matrix-by-rows
  36.343 +  "Define a matrix by giving its rows."
  36.344 +  [& rows]
  36.345 +  (if
  36.346 +   (not (all-equal? (map count rows)))
  36.347 +   (throw (Exception. "All rows in a matrix must have the same number of elements."))
  36.348 +   (incanter.core/matrix (vec rows))))
  36.349 +
  36.350 +(defn matrix-by-cols
  36.351 +  "Define a matrix by giving its columns"
  36.352 +  [& cols]
  36.353 +  (if (not (all-equal? (map count cols)))
  36.354 +   (throw (Exception. "All columns in a matrix must have the same number of elements."))
  36.355 +   (incanter.core/matrix (vec (apply map vector cols)))))
  36.356 +
  36.357 +(defn identity-matrix
  36.358 +  "Define a square matrix of size n-by-n with 1s along the diagonal and
  36.359 +  0s everywhere else."
  36.360 +  [n]
  36.361 +  (incanter.core/identity-matrix n))
  36.362 +
  36.363 +
  36.364 +
  36.365 +(extend-protocol Arithmetic
  36.366 +  incanter.Matrix
  36.367 +  (one [matrix]
  36.368 +       (if (square? matrix)
  36.369 +	 (identity-matrix (count-rows matrix))
  36.370 +	 (throw (Exception. "Non-square matrices have no multiplicative unit."))))
  36.371 +  (zero [matrix]
  36.372 +	(apply matrix-by-rows (map zero (rows matrix))))
  36.373 +  (negate [matrix]
  36.374 +	  (apply matrix-by-rows (map negate (rows matrix))))
  36.375 +  (invert [matrix]
  36.376 +	  (incanter.core/solve matrix)))
  36.377 +
  36.378 +
  36.379 +
  36.380 +(defmulti coerce-to-matrix
  36.381 + "Converts x into a matrix, if possible."
  36.382 + type)
  36.383 +
  36.384 +(defmethod coerce-to-matrix incanter.Matrix [x] x)
  36.385 +(defmethod coerce-to-matrix Tuple [x]
  36.386 +	   (if (apply numbers? (seq x))
  36.387 +	     (if (up? x)
  36.388 +	     (matrix-by-cols (seq x))
  36.389 +	     (matrix-by-rows (seq x)))
  36.390 +	     (throw (Exception. "Non-numerical tuple cannot be converted into a matrix.")))) 
  36.391 +	     
  36.392 +  
  36.393 +
  36.394 +
  36.395 +
  36.396 +;; (defn matrix-by-cols
  36.397 +;;   "Define a matrix by giving its columns."
  36.398 +;;   [& cols]
  36.399 +;;   (cond
  36.400 +;;    (not (all-equal? (map count cols)))
  36.401 +;;    (throw (Exception. "All columns in a matrix must have the same number of elements."))
  36.402 +;;    :else
  36.403 +;;    (reify Matrix
  36.404 +;; 	  (cols [this] (map up cols))
  36.405 +;; 	  (rows [this] (map down (apply map vector cols)))
  36.406 +;; 	  (diagonal [this] (map-indexed (fn [i col] (nth col i) cols)))
  36.407 +;; 	  (trace [this]
  36.408 +;; 		 (if (not= (count-cols this) (count-rows this))
  36.409 +;; 		   (throw (Exception.
  36.410 +;; 			   "Cannot take the trace of a non-square matrix."))
  36.411 +;; 		   (reduce + (diagonal this))))
  36.412 +	  
  36.413 +;; 	  (determinant [this]
  36.414 +;; 		       (if (not= (count-cols this) (count-rows this))
  36.415 +;; 			 (throw (Exception.
  36.416 +;; 				 "Cannot take the determinant of a non-square matrix."))
  36.417 +;; 			 (reduce * (map-indexed (fn [i col] (nth col i)) cols))))
  36.418 +;; 	  )))
  36.419 +
  36.420 +(extend-protocol Matrix  Tuple
  36.421 +		 (rows [this] (if (down? this)
  36.422 +				(list this)
  36.423 +				(map (comp up vector) this)))
  36.424 +
  36.425 +		 (cols [this] (if (up? this)
  36.426 +				(list this)
  36.427 +				(map (comp down vector) this))
  36.428 +		 ))
  36.429 +  
  36.430 +(defn matrix-multiply
  36.431 +  "Returns the matrix resulting from the matrix multiplication of the given arguments."
  36.432 +  ([A] (coerce-to-matrix A))
  36.433 +  ([A B] (incanter.core/mmult (coerce-to-matrix A) (coerce-to-matrix B)))
  36.434 +  ([M1 M2 & Ms] (reduce matrix-multiply (matrix-multiply M1 M2) Ms)))
  36.435 +
  36.436 +#+end_src
  36.437 +
  36.438 +
  36.439 +** Power Series
  36.440 +#+srcname power-series
  36.441 +#+begin_src clojure
  36.442 +(in-ns 'sicm.utils)
  36.443 +(use 'clojure.contrib.def)
  36.444 +
  36.445 +
  36.446 +
  36.447 +(defn series-fn
  36.448 +  "The function corresponding to the given power series."
  36.449 +  [series]
  36.450 +  (fn [x]
  36.451 +    (reduce +
  36.452 +	    (map-indexed  (fn[n x] (* (float (nth series n)) (float(java.lang.Math/pow (float x) n)) ))
  36.453 +			  (range 20)))))
  36.454 +
  36.455 +(deftype PowerSeries
  36.456 +  [coll]
  36.457 +  clojure.lang.Seqable
  36.458 +  (seq [this] (seq (.coll this)))
  36.459 +  
  36.460 +  clojure.lang.Indexed
  36.461 +  (nth [this n] (nth (.coll this) n 0))
  36.462 +  (nth [this n not-found] (nth (.coll this) n not-found))
  36.463 +
  36.464 +  ;; clojure.lang.IFn
  36.465 +  ;; (call [this] (throw(Exception.)))
  36.466 +  ;; (invoke [this & args] args
  36.467 +  ;; 	  (let [f 
  36.468 +  ;; )
  36.469 +  ;; (run [this] (throw(Exception.)))
  36.470 +  )
  36.471 +
  36.472 +(defn power-series
  36.473 +  "Returns a power series with the items of the coll as its
  36.474 +  coefficients. Trailing zeros are added to the end of coll."
  36.475 +  [coeffs]
  36.476 +  (PowerSeries. coeffs))
  36.477 +
  36.478 +(defn power-series-indexed
  36.479 +  "Returns a power series consisting of the result of mapping f to the non-negative integers."
  36.480 +  [f]
  36.481 +  (PowerSeries. (map f (range))))
  36.482 +
  36.483 +
  36.484 +(defn-memo nth-partial-sum
  36.485 +  ([series n]
  36.486 +     (if (zero? n) (first series)
  36.487 +	 (+ (nth series n)
  36.488 +	    (nth-partial-sum series (dec n))))))
  36.489 +
  36.490 +(defn partial-sums [series]
  36.491 +  (lazy-seq (map nth-partial-sum (range))))
  36.492 +
  36.493 +
  36.494 +
  36.495 +
  36.496 +(def cos-series
  36.497 +     (power-series-indexed
  36.498 +      (fn[n]
  36.499 +	(if (odd? n) 0
  36.500 +	    (/
  36.501 +	     (reduce *
  36.502 +		     (reduce * (repeat (/ n 2) -1))
  36.503 +		     (range 1 (inc n)))
  36.504 +	     )))))
  36.505 +
  36.506 +(def sin-series
  36.507 +     (power-series-indexed
  36.508 +      (fn[n]
  36.509 +	(if (even? n) 0
  36.510 +	    (/
  36.511 +	     (reduce *
  36.512 +		     (reduce * (repeat (/ (dec n) 2) -1))
  36.513 +		     (range 1 (inc n)))
  36.514 +	     )))))
  36.515 +
  36.516 +#+end_src
  36.517 +
  36.518 +
  36.519 +* Basic Utilities
  36.520 +
  36.521 +** Sequence manipulation
  36.522 +
  36.523 +#+srcname: seq-manipulation
  36.524 +#+begin_src clojure
  36.525 +(ns sicm.utils)
  36.526 +
  36.527 +(defn do-up
  36.528 +  "Apply f to each number from low to high, presumably for
  36.529 +  side-effects."
  36.530 +  [f low high]
  36.531 +  (doseq [i (range low high)] (f i)))
  36.532 +   
  36.533 +(defn do-down
  36.534 +  "Apply f to each number from high to low, presumably for
  36.535 +   side-effects."
  36.536 +  [f high low]
  36.537 +  (doseq [i (range high low -1)] (f i)))
  36.538 +
  36.539 +
  36.540 +(defn all-equal? [coll]
  36.541 +  (if (empty? (rest coll)) true
  36.542 +      (and (= (first coll) (second coll))
  36.543 +	   (recur (rest coll))))))
  36.544 +
  36.545 +(defn multiplier
  36.546 +  "Returns a function that 'multiplies' the members of a collection,
  36.547 +returning unit if called on an empty collection."
  36.548 +  [multiply unit]
  36.549 +  (fn [coll] ((partial reduce multiply unit) coll)))
  36.550 +
  36.551 +(defn divider
  36.552 +  "Returns a function that 'divides' the first element of a collection
  36.553 +by the 'product' of the rest of the collection."
  36.554 +  [divide multiply invert unit]
  36.555 +  (fn [coll]
  36.556 +    (apply
  36.557 +     (fn
  36.558 +       ([] unit)
  36.559 +       ([x] (invert x))
  36.560 +       ([x y] (divide x y))
  36.561 +       ([x y & zs] (divide x (reduce multiply y zs))))
  36.562 +     coll)))
  36.563 +
  36.564 +(defn left-circular-shift
  36.565 +  "Remove the first element of coll, adding it to the end of coll."
  36.566 +  [coll]
  36.567 +  (concat (rest coll) (take 1 coll)))
  36.568 +
  36.569 +(defn right-circular-shift
  36.570 +  "Remove the last element of coll, adding it to the front of coll."
  36.571 +  [coll]
  36.572 +  (cons (last coll) (butlast coll)))
  36.573 +#+end_src
  36.574 +
  36.575 +
  36.576 +
  36.577 +
  36.578 +** Ranges, Airity and Function Composition
  36.579 +#+srcname: arity
  36.580 +#+begin_src clojure
  36.581 +(in-ns 'sicm.utils)
  36.582 +(def infinity Double/POSITIVE_INFINITY)
  36.583 +(defn infinite? [x] (Double/isInfinite x))
  36.584 +(def finite? (comp not infinite?)) 
  36.585 +
  36.586 +(defn arity-min
  36.587 +  "Returns the smallest number of arguments f can take."
  36.588 +  [f]
  36.589 +  (apply
  36.590 +   min
  36.591 +   (map (comp alength #(.getParameterTypes %))
  36.592 +	(filter (comp (partial = "invoke") #(.getName %))
  36.593 +		(.getDeclaredMethods (class f))))))
  36.594 +  
  36.595 +(defn arity-max
  36.596 +  "Returns the largest number of arguments f can take, possibly
  36.597 +  Infinity."
  36.598 +  [f]
  36.599 +  (let [methods (.getDeclaredMethods (class f))]
  36.600 +    (if (not-any? (partial = "doInvoke") (map #(.getName %) methods))
  36.601 +      (apply max
  36.602 +	     (map (comp alength #(.getParameterTypes %))
  36.603 +		  (filter (comp (partial = "invoke") #(.getName %))  methods)))
  36.604 +      infinity)))
  36.605 +
  36.606 +
  36.607 +(def ^{:arglists '([f])
  36.608 +       :doc "Returns a two-element list containing the minimum and
  36.609 +     maximum number of args that f can take."}
  36.610 +     arity-interval
  36.611 +     (juxt arity-min arity-max))
  36.612 +
  36.613 +
  36.614 +
  36.615 +;; --- intervals
  36.616 +
  36.617 +(defn intersect
  36.618 +  "Returns the interval of overlap between interval-1 and interval-2"
  36.619 +  [interval-1 interval-2]
  36.620 +  (if (or (empty? interval-1) (empty? interval-2)) []
  36.621 +      (let [left (max (first interval-1) (first interval-2))
  36.622 +	    right (min (second interval-1) (second interval-2))]
  36.623 +	(if (> left right) []
  36.624 +	    [left right]))))
  36.625 +
  36.626 +(defn same-endpoints?
  36.627 +  "Returns true if the left endpoint is the same as the right
  36.628 +  endpoint."
  36.629 +  [interval]
  36.630 +  (= (first interval) (second interval)))
  36.631 +
  36.632 +(defn naturals?
  36.633 +  "Returns true if the left endpoint is 0 and the right endpoint is
  36.634 +infinite."
  36.635 +  [interval]
  36.636 +  (and (zero? (first interval))
  36.637 +       (infinite? (second interval))))
  36.638 + 
  36.639 +
  36.640 +(defn fan-in
  36.641 +  "Returns a function that pipes its input to each of the gs, then
  36.642 +  applies f to the list of results. Consequently, f must be able to
  36.643 +  take a number of arguments equal to the number of gs."
  36.644 +  [f & gs]
  36.645 +  (fn [& args]
  36.646 +    (apply f (apply (apply juxt gs) args))))
  36.647 +
  36.648 +(defn fan-in
  36.649 +  "Returns a function that pipes its input to each of the gs, then applies f to the list of results. The resulting function takes any number of arguments, but will fail if given arguments that are incompatible with any of the gs."
  36.650 +  [f & gs]
  36.651 +  (comp (partial apply f) (apply juxt gs)))
  36.652 +
  36.653 +
  36.654 +
  36.655 +(defmacro airty-blah-sad [f n more?]
  36.656 +  (let [syms (vec (map (comp gensym (partial str "x")) (range n)))
  36.657 +	 optional (gensym "xs")]
  36.658 +    (if more?
  36.659 +      `(fn ~(conj syms '& optional)
  36.660 +	 (apply ~f ~@syms ~optional))
  36.661 +      `(fn ~syms (~f ~@syms)))))
  36.662 +
  36.663 +(defmacro airt-whaa* [f n more?]
  36.664 +  `(airty-blah-sad ~f ~n ~more?))
  36.665 +
  36.666 +
  36.667 +
  36.668 +
  36.669 +(defn fan-in*
  36.670 +  "Returns a function that pipes its input to each of the gs, then
  36.671 +  applies f to the list of results. Unlike fan-in, fan-in* strictly
  36.672 +  enforces arity: it will fail if the gs do not have compatible
  36.673 +  arities."
  36.674 +  [f & gs]
  36.675 +  (let [arity-in (reduce intersect (map arity-interval gs))
  36.676 +	left (first arity-in)
  36.677 +	right (second arity-in)
  36.678 +	composite (fan-in f gs)
  36.679 +	]
  36.680 +    (cond
  36.681 +     (empty? arity-in)
  36.682 +     (throw (Exception. "Cannot compose functions with incompatible arities."))
  36.683 +
  36.684 +     (not
  36.685 +      (or (= left right)
  36.686 +	  (and (finite? left)
  36.687 +	       (= right infinity))))
  36.688 +	 
  36.689 +     (throw (Exception.
  36.690 +	     "Compose can only handle arities of the form [n n] or [n infinity]"))
  36.691 +     :else
  36.692 +     (airty-blah-sad composite left (= right infinity)))))
  36.693 +    
  36.694 +
  36.695 +
  36.696 +(defn compose-n "Compose any number of functions together."
  36.697 +  ([] identity)
  36.698 +  ([f] f)
  36.699 +  ([f & fs]
  36.700 +  (let [fns (cons f fs)]
  36.701 +    (compose-bin (reduce fan-in (butlast fs)) (last fs))))
  36.702 +)
  36.703 +
  36.704 +
  36.705 +
  36.706 +
  36.707 +	   
  36.708 +
  36.709 +(defn iterated
  36.710 +  ([f n id] (reduce comp id (repeat n f)))
  36.711 +  ([f n] (reduce comp identity (repeat n f))))
  36.712 +
  36.713 +(defn iterate-until-stable
  36.714 +  "Repeatedly applies f to x, returning the first result that is close
  36.715 +enough to its predecessor."
  36.716 +  [f close-enough? x]
  36.717 +  (second (swank.util/find-first
  36.718 +	   (partial apply close-enough?)
  36.719 +	   (partition 2 1 (iterate f x)))))
  36.720 +
  36.721 +(defn lexical< [x y]
  36.722 +  (neg? (compare (str x) (str y))))
  36.723 +
  36.724 +
  36.725 +;; do-up
  36.726 +;; do-down
  36.727 +(def make-pairwise-test comparator)
  36.728 +;;all-equal?
  36.729 +(def accumulation multiplier)
  36.730 +(def inverse-accumulation divider)
  36.731 +;;left-circular-shift
  36.732 +;;right-circular-shift
  36.733 +(def exactly-n? same-endpoints?)
  36.734 +(def any-number? naturals?)
  36.735 +;; TODO compose
  36.736 +;; TODO compose-n
  36.737 +;; identity
  36.738 +(def compose-2 fan-in)
  36.739 +(def compose-bin fan-in*)
  36.740 +(def any? (constantly true))
  36.741 +(def none? (constantly false))
  36.742 +(def constant constantly)
  36.743 +(def joint-arity intersect)
  36.744 +(def a-reduce reduce)
  36.745 +;; filter
  36.746 +(def make-map (partial partial map) )
  36.747 +(def bracket juxt)
  36.748 +;; TODO apply-to-all
  36.749 +;; TODO nary-combine
  36.750 +;; TODO binary-combine
  36.751 +;; TODO unary-combine
  36.752 +;; iterated
  36.753 +;; iterate-until-stable
  36.754 +(def make-function-of-vector (partial partial map))
  36.755 +(def make-function-of-arguments (fn [f] (fn [& args] (f args))))
  36.756 +(def alphaless lexical<)
  36.757 +
  36.758 +#+end_src
  36.759 +
  36.760 +
  36.761 +
  36.762 +
  36.763 +
  36.764 +
  36.765 +
  36.766 +: 
  36.767 +
  36.768 +*  Numerical Methods
  36.769 +#+srcname: numerical-methods
  36.770 +#+begin_src clojure
  36.771 +(in-ns 'sicm.utils)
  36.772 +(import java.lang.Math)
  36.773 +(use 'clojure.contrib.def)
  36.774 +
  36.775 +;; ---- USEFUL CONSTANTS
  36.776 +
  36.777 +(defn machine-epsilon
  36.778 +  "Smallest value representable on your machine, as determined by
  36.779 +successively dividing a number in half until consecutive results are
  36.780 +indistinguishable."
  36.781 +  []
  36.782 +  (ffirst
  36.783 +   (drop-while
  36.784 +    (comp not zero? second)
  36.785 +    (partition 2 1
  36.786 +	       (iterate (partial * 0.5) 1)))))
  36.787 +
  36.788 +
  36.789 +(def pi (Math/PI))
  36.790 +(def two-pi (* 2 pi))
  36.791 +
  36.792 +(def eulers-gamma 0.5772156649015328606065)
  36.793 +
  36.794 +(def phi (/ (inc (Math/sqrt 5)) 2))
  36.795 +
  36.796 +(def ln2 (Math/log 2))
  36.797 +(def ln10 (Math/log 10))
  36.798 +(def exp10 #(Math/pow 10 %))
  36.799 +(def exp2 #(Math/pow 2 %))
  36.800 +
  36.801 +
  36.802 +;;
  36.803 +
  36.804 +;; ---- ANGLES AND TRIGONOMETRY
  36.805 +
  36.806 +(defn angle-restrictor
  36.807 +  "Returns a function that ensures that angles lie in the specified interval of length two-pi."
  36.808 +  [max-angle]
  36.809 +  (let [min-angle (- max-angle two-pi)]
  36.810 +    (fn [x]
  36.811 +      (if (and
  36.812 +	   (<= min-angle x)
  36.813 +	   (< x max-angle))
  36.814 +	x
  36.815 +	(let [corrected-x (- x (* two-pi (Math/floor (/ x two-pi))))]
  36.816 +	  (if (< corrected-x max-angle)
  36.817 +	    corrected-x
  36.818 +	    (- corrected-x two-pi)))))))
  36.819 +
  36.820 +(defn angle-restrict-pi
  36.821 +  "Coerces angles to lie in the interval from -pi to pi."
  36.822 +  [angle]
  36.823 +  ((angle-restrictor pi) angle))
  36.824 +
  36.825 +(defn angle-restrict-two-pi
  36.826 +  "Coerces angles to lie in the interval from zero to two-pi"
  36.827 +  [angle]
  36.828 +  ((angle-restrictor two-pi) angle))
  36.829 +
  36.830 +
  36.831 +
  36.832 +
  36.833 +(defn invert [x] (/ x))
  36.834 +(defn negate [x] (- x))
  36.835 +
  36.836 +(defn exp [x] (Math/exp x))
  36.837 +
  36.838 +(defn sin [x] (Math/sin x))
  36.839 +(defn cos [x] (Math/cos x))
  36.840 +(defn tan [x] (Math/tan x))
  36.841 +
  36.842 +(def sec (comp invert cos))
  36.843 +(def csc (comp invert sin))
  36.844 +
  36.845 +(defn sinh [x] (Math/sinh x))
  36.846 +(defn cosh [x] (Math/cosh x))
  36.847 +(defn tanh [x] (Math/tanh x))
  36.848 +
  36.849 +(def sech (comp invert cosh))
  36.850 +(def csch (comp invert sinh))
  36.851 +
  36.852 +
  36.853 +;; ------------
  36.854 +
  36.855 +(defn factorial
  36.856 +  "Computes the factorial of the nonnegative integer n."
  36.857 +  [n]
  36.858 +  (if (neg? n)
  36.859 +    (throw (Exception. "Cannot compute the factorial of a negative number."))
  36.860 +    (reduce * 1 (range 1 (inc n)))))
  36.861 +
  36.862 +(defn exact-quotient [n d] (/ n d))
  36.863 +
  36.864 +(defn binomial-coefficient
  36.865 +  "Computes the number of different ways to choose m elements from n."
  36.866 +  [n m]
  36.867 +  (assert (<= 0 m n))
  36.868 +  (let [difference (- n m)]
  36.869 +    (exact-quotient
  36.870 +     (reduce * (range n (max difference m) -1 ))
  36.871 +     (factorial (min difference m)))))
  36.872 +
  36.873 +(defn-memo stirling-1
  36.874 +  "Stirling numbers of the first kind: the number of permutations of n
  36.875 +  elements with exactly m permutation cycles. "
  36.876 +  [n k]
  36.877 +  ;(assert (<= 1 k n))
  36.878 +  (if (zero? n)
  36.879 +    (if (zero? k) 1 0)
  36.880 +    (+ (stirling-1 (dec n) (dec k))
  36.881 +       (* (dec n) (stirling-1 (dec n) k)))))
  36.882 +
  36.883 +(defn-memo stirling-2 ;;count-partitions
  36.884 +  "Stirling numbers of the second kind: the number of ways to partition a set of n elements into k subsets."
  36.885 +  [n k]
  36.886 +  (cond
  36.887 +   (= k 1) 1
  36.888 +   (= k n) 1
  36.889 +   :else (+ (stirling-2 (dec n) (dec k))
  36.890 +	    (* k (stirling-2 (dec n) k)))))
  36.891 +
  36.892 +(defn harmonic-number [n]
  36.893 +  (/ (stirling-1 (inc n) 2)
  36.894 +     (factorial n)))
  36.895 +
  36.896 +
  36.897 +(defn sum
  36.898 +  [f low high]
  36.899 +  (reduce + (map f (range low (inc high)))))
  36.900 +
  36.901 +#+end_src
  36.902 +
  36.903 +
  36.904 +
  36.905 +
  36.906 +
  36.907 +
  36.908 +
  36.909 +
  36.910 +
  36.911 +
  36.912 +
  36.913 +
  36.914 +* Differentiation
  36.915 +
  36.916 +We compute derivatives by passing special *differential objects* $[x,
  36.917 +dx]$ through functions. Roughly speaking, applying a function $f$ to a
  36.918 +differential object \([x, dx]\) should produce a new differential
  36.919 +object $[f(x),\,Df(x)\cdot dx]$.
  36.920 +
  36.921 +\([x,\,dx]\xrightarrow{\quad f \quad}[f(x),\,Df(x)\cdot dx]\)
  36.922 +Notice that you can obtain the derivative of $f$ from this
  36.923 +differential object, as it is the coefficient of the $dx$ term. Also,
  36.924 +as you apply successive functions using this rule, you get the
  36.925 +chain-rule answer you expect:
  36.926 +
  36.927 +\([f(x),\,Df(x)\cdot dx]\xrightarrow{\quad g\quad} [gf(x),\,
  36.928 +Dgf(x)\cdot Df(x) \cdot dx ]\)
  36.929 +
  36.930 +In order to generalize to multiple variables and multiple derivatives,
  36.931 +we use a *power series of differentials*, a sortred infinite sequence which
  36.932 +contains all terms like $dx\cdot dy$, $dx^2\cdot dy$, etc.
  36.933 +
  36.934 +
  36.935 +#+srcname:differential
  36.936 +#+begin_src clojure
  36.937 +(in-ns 'sicm.utils)
  36.938 +(use 'clojure.contrib.combinatorics)
  36.939 +(use 'clojure.contrib.generic.arithmetic)
  36.940 +
  36.941 +(defprotocol DifferentialTerm
  36.942 +  "Protocol for an infinitesimal quantity."
  36.943 +  (coefficient [this])
  36.944 +  (partials [this]))
  36.945 +
  36.946 +(extend-protocol DifferentialTerm
  36.947 +  java.lang.Number
  36.948 +  (coefficient [this] this)
  36.949 +  (partials [this] []))
  36.950 +
  36.951 +(deftype DifferentialSeq
  36.952 +  [terms]
  36.953 +  clojure.lang.IPersistentCollection
  36.954 +  (cons [this x]
  36.955 +	(throw (Exception. x))
  36.956 +	(DifferentialSeq. (cons x terms)))
  36.957 + ;; (seq [this] (seq terms))
  36.958 +  (count [this] (count terms))
  36.959 +  (empty [this] (empty? terms)))
  36.960 +
  36.961 +
  36.962 +
  36.963 +
  36.964 +
  36.965 +
  36.966 +
  36.967 +
  36.968 +
  36.969 +
  36.970 +
  36.971 +(defn coerce-to-differential-seq [x]
  36.972 +  (cond
  36.973 +   (= (type x) DifferentialSeq) x
  36.974 +   (satisfies? DifferentialTerm x) (DifferentialSeq. x)))
  36.975 +
  36.976 +
  36.977 +(defn differential-term
  36.978 +  "Returns a differential term with the given coefficient and
  36.979 +  partials. Coefficient may be any arithmetic object; partials must
  36.980 +  be a list of non-negative integers."
  36.981 +  [coefficient partials]
  36.982 +  (reify DifferentialTerm
  36.983 +	 (partials [_] (set partials))
  36.984 +	 (coefficient [_] coefficient)))
  36.985 +
  36.986 +
  36.987 +
  36.988 +(defn differential-seq*
  36.989 +  ([coefficient partials]
  36.990 +     (DifferentialSeq. [(differential-term coefficient partials)]))
  36.991 +  ([coefficient partials & cps]
  36.992 +     (if cps
  36.993 +       
  36.994 +	
  36.995 +
  36.996 +
  36.997 +(defn differential-seq
  36.998 +  "Constructs a sequence of differential terms from a numerical
  36.999 +coefficient and a list of keys for variables. If no coefficient is supplied, uses 1."
 36.1000 +  ([variables] (differential-seq 1 variables))
 36.1001 +  ([coefficient variables & cvs]
 36.1002 +     (if (number? coefficient)
 36.1003 +       (conj (assoc {} (apply sorted-set variables) coefficient)
 36.1004 +	     (if (empty? cvs)
 36.1005 +	       nil
 36.1006 +	       (apply differential-seq cvs)))
 36.1007 +       (apply differential-seq 1 coefficient 1 variables cvs)  
 36.1008 +       )))
 36.1009 +
 36.1010 +
 36.1011 +(defn differential-add
 36.1012 +  "Add two differential sequences by combining like terms."
 36.1013 +  [dseq1 dseq2]
 36.1014 +  (merge-with + dseq1 dseq2))
 36.1015 +
 36.1016 +(defn differential-multiply
 36.1017 +  "Multiply two differential sequences. The square of any differential variable is zero since differential variables are infinitesimally small."
 36.1018 +  [dseq1 dseq2]
 36.1019 +  (reduce
 36.1020 +   (fn [m [[vars1 coeff1] [vars2 coeff2]]]
 36.1021 +     (if (empty? (clojure.set/intersection vars1 vars2))
 36.1022 +       (assoc m (clojure.set/union vars1 vars2) (* coeff1 coeff2))
 36.1023 +       m))
 36.1024 +   {}
 36.1025 +  (clojure.contrib.combinatorics/cartesian-product
 36.1026 +   dseq1
 36.1027 +   dseq2)))
 36.1028 +
 36.1029 +
 36.1030 +(defn big-part
 36.1031 +  "Returns the part of the differential sequence that is finite,
 36.1032 +  i.e. not infinitely small."
 36.1033 +  [dseq]
 36.1034 +  (let
 36.1035 +      [keys (sort-by count (keys dseq))
 36.1036 +       smallest-var (last(last keys))]
 36.1037 +    (apply hash-map
 36.1038 +	   (reduce concat
 36.1039 +		   (remove (comp smallest-var first) dseq)))))
 36.1040 +
 36.1041 +(defn small-part
 36.1042 +  "Returns the part of the differential sequence that is
 36.1043 +  infinitesimal."
 36.1044 +  [dseq]
 36.1045 +  (let
 36.1046 +      [keys (sort-by count (keys dseq))
 36.1047 +       smallest-var (last(last keys))]
 36.1048 +    (apply hash-map
 36.1049 +	   (reduce concat
 36.1050 +		   (filter (comp smallest-var first) dseq)))))
 36.1051 +
 36.1052 +(defn big-part
 36.1053 +  "Returns the 'finite' part of the differential sequence."
 36.1054 +  [dseq]
 36.1055 +  (let
 36.1056 +      [keys (sort-by count (keys dseq))
 36.1057 +       smallest-var (last (last keys))]
 36.1058 +    (apply hash-map
 36.1059 +    (reduce concat
 36.1060 +           (filter (remove smallest-var first) dseq)
 36.1061 +	   ))))
 36.1062 +
 36.1063 +
 36.1064 +(defn small-part
 36.1065 +  "Returns the 'infinitesimal' part of the differential sequence."
 36.1066 +  [dseq]
 36.1067 +    (let
 36.1068 +      [keys (sort-by count (keys dseq))
 36.1069 +       smallest-var (last (last keys))]
 36.1070 +
 36.1071 +    (apply hash-map
 36.1072 +    (reduce concat
 36.1073 +	    (filter (comp smallest-var first) dseq)
 36.1074 +	    ))))
 36.1075 +
 36.1076 +(defn linear-approximator
 36.1077 +  "Returns the function that corresponds to unary-fn but which accepts and returns differential objects."
 36.1078 +  ([unary-f dfdx]
 36.1079 +     (fn F [dseq]
 36.1080 +       (differential-add
 36.1081 +	(unary-f (big-part dseq))
 36.1082 +	(differential-multiply
 36.1083 +	 (dfdx (big-part dseq))
 36.1084 +	 (small-part dseq))))))
 36.1085 +
 36.1086 +
 36.1087 +
 36.1088 +
 36.1089 +
 36.1090 +
 36.1091 +;; ;; A differential term consists of a numerical coefficient and a
 36.1092 +;; ;; sorted  
 36.1093 +;; (defrecord DifferentialTerm [coefficient variables])
 36.1094 +;; (defmethod print-method DifferentialTerm
 36.1095 +;;    [o w]
 36.1096 +;;     (print-simple
 36.1097 +;;      (apply str (.coefficient o)(map (comp (partial str "d") name) (.variables o)))
 36.1098 +;;      w))
 36.1099 +
 36.1100 +
 36.1101 +;; (defn differential-seq
 36.1102 +;;   "Constructs a sequence of differential terms from a numerical
 36.1103 +;; coefficient and a list of keywords for variables. If no coefficient is
 36.1104 +;; supplied, uses 1."
 36.1105 +;;   ([variables] (differential-seq 1 variables))
 36.1106 +;;   ([coefficient variables]
 36.1107 +;;      (list
 36.1108 +;;       (DifferentialTerm. coefficient (apply sorted-set variables))))
 36.1109 +;;   ([coefficient variables & cvs]
 36.1110 +;;      (sort-by
 36.1111 +;;       #(vec(.variables %))
 36.1112 +;;       (concat (differential-seq coefficient variables) (apply differential-seq cvs)))))
 36.1113 +
 36.1114 +#+end_src
 36.1115 +
 36.1116 +
 36.1117 +
 36.1118 +
 36.1119 +
 36.1120 +
 36.1121 +
 36.1122 +
 36.1123 +
 36.1124 +
 36.1125 +
 36.1126 +
 36.1127 +
 36.1128 +* Symbolic Manipulation
 36.1129 +
 36.1130 +#+srcname:symbolic
 36.1131 +#+begin_src clojure
 36.1132 +(in-ns 'sicm.utils)
 36.1133 +
 36.1134 +(deftype Symbolic [type expression]
 36.1135 +  Object
 36.1136 +  (equals [this that]
 36.1137 +	  (cond
 36.1138 +	   (= (.expression this) (.expression that)) true
 36.1139 +	   :else
 36.1140 +	   (Symbolic.
 36.1141 +	    java.lang.Boolean
 36.1142 +	    (list '= (.expression this) (.expression that)))
 36.1143 +	  )))
 36.1144 +
 36.1145 +
 36.1146 +
 36.1147 +
 36.1148 +(deftype AbstractSet [glyph membership-test])
 36.1149 +(defn member? [abstract-set x]
 36.1150 +  ((.membership-test abstract-set) x))
 36.1151 +
 36.1152 +;; ------------ Some important AbstractSets
 36.1153 +
 36.1154 +
 36.1155 +(def Real
 36.1156 +     (AbstractSet.
 36.1157 +      'R
 36.1158 +      (fn[x](number? x))))
 36.1159 +
 36.1160 +
 36.1161 +;; ------------ Create new AbstractSets from existing ones
 36.1162 +
 36.1163 +(defn abstract-product
 36.1164 +  "Gives the cartesian product of abstract sets."
 36.1165 +  ([sets]
 36.1166 +       (if (= (count sets) 1) (first sets)
 36.1167 +	   (AbstractSet.
 36.1168 +	    (symbol
 36.1169 +	     (apply str
 36.1170 +		    (interpose 'x (map #(.glyph %) sets))))
 36.1171 +	   (fn [x]
 36.1172 +	     (and
 36.1173 +	      (coll? x)
 36.1174 +	      (= (count sets) (count x))
 36.1175 +	      (reduce #(and %1 %2)
 36.1176 +		      true
 36.1177 +		      (map #(member? %1 %2) sets x)))))))
 36.1178 +  ([abstract-set n]
 36.1179 +     (abstract-product (repeat n abstract-set))))
 36.1180 +
 36.1181 +
 36.1182 +	      
 36.1183 +(defn abstract-up
 36.1184 +  "Returns the abstract set of all up-tuples whose items belong to the
 36.1185 +  corresponding abstract sets in coll."
 36.1186 +  ([coll]
 36.1187 +     (AbstractSet.
 36.1188 +      (symbol (str "u["
 36.1189 +		   (apply str
 36.1190 +			  (interpose " "
 36.1191 +				     (map #(.glyph %) coll)))
 36.1192 +		   "]"))
 36.1193 +      (fn [x]
 36.1194 +	(and
 36.1195 +	 (satisfies? Spinning x)
 36.1196 +	 (up? x)
 36.1197 +	 (= (count coll) (count x))
 36.1198 +	 (reduce
 36.1199 +	  #(and %1 %2)
 36.1200 +	  true
 36.1201 +	  (map #(member? %1 %2) coll x))))))
 36.1202 +  ([abstract-set n]
 36.1203 +     (abstract-up (repeat n abstract-set))))
 36.1204 +
 36.1205 +
 36.1206 +(defn abstract-down
 36.1207 +  "Returns the abstract set of all down-tuples whose items belong to the
 36.1208 +  corresponding abstract sets in coll."
 36.1209 +  ([coll]
 36.1210 +     (AbstractSet.
 36.1211 +      (symbol (str "d["
 36.1212 +		   (apply str
 36.1213 +			  (interpose " "
 36.1214 +				     (map #(.glyph %) coll)))
 36.1215 +		   "]"))
 36.1216 +      (fn [x]
 36.1217 +	(and
 36.1218 +	 (satisfies? Spinning x)
 36.1219 +	 (down? x)
 36.1220 +	 (= (count coll) (count x))
 36.1221 +	 (reduce
 36.1222 +	  #(and %1 %2)
 36.1223 +	  true
 36.1224 +	  (map #(member? %1 %2) coll x))))))
 36.1225 +  ([abstract-set n]
 36.1226 +     (abstract-down (repeat n abstract-set))))
 36.1227 +
 36.1228 +	      
 36.1229 +
 36.1230 +
 36.1231 +
 36.1232 +					;-------ABSTRACT FUNCTIONS
 36.1233 +(defrecord AbstractFn
 36.1234 +  [#^AbstractSet domain #^AbstractSet codomain])
 36.1235 +
 36.1236 +
 36.1237 +(defmethod print-method AbstractFn
 36.1238 +  [o w]
 36.1239 +  (print-simple
 36.1240 +   (str
 36.1241 +    "f:"
 36.1242 +   (.glyph (:domain o))
 36.1243 +   "-->"
 36.1244 +   (.glyph (:codomain o))) w))
 36.1245 +#+end_src
 36.1246 +
 36.1247 +
 36.1248 +* COMMENT 
 36.1249 +#+begin_src clojure :tangle utils.clj
 36.1250 +(ns sicm.utils)
 36.1251 +
 36.1252 +					;***** GENERIC ARITHMETIC
 36.1253 +<<generic-arithmetic>>
 36.1254 +
 36.1255 +
 36.1256 +					;***** TUPLES AND MATRICES
 36.1257 +<<tuples>>
 36.1258 +<<tuples-2>>
 36.1259 +					;***** MATRICES
 36.1260 +<<matrices>>
 36.1261 +
 36.1262 +#+end_src
 36.1263 +
 36.1264 +
 36.1265 +
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/sicm/deriv.html	Fri Oct 28 00:03:05 2011 -0700
    37.3 @@ -0,0 +1,240 @@
    37.4 +<?xml version="1.0" encoding="utf-8"?>
    37.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    37.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    37.7 +<html xmlns="http://www.w3.org/1999/xhtml"
    37.8 +lang="en" xml:lang="en">
    37.9 +<head>
   37.10 +<title>An Unambiguous Notation for Derivatives</title>
   37.11 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
   37.12 +<meta name="generator" content="Org-mode"/>
   37.13 +<meta name="generated" content="2011-08-08 02:49:24 EDT"/>
   37.14 +<meta name="author" content="Dylan Holmes"/>
   37.15 +<meta name="description" content=""/>
   37.16 +<meta name="keywords" content=""/>
   37.17 +<style type="text/css">
   37.18 + <!--/*--><![CDATA[/*><!--*/
   37.19 +  html { font-family: Times, serif; font-size: 12pt; }
   37.20 +  .title  { text-align: center; }
   37.21 +  .todo   { color: red; }
   37.22 +  .done   { color: green; }
   37.23 +  .tag    { background-color: #add8e6; font-weight:normal }
   37.24 +  .target { }
   37.25 +  .timestamp { color: #bebebe; }
   37.26 +  .timestamp-kwd { color: #5f9ea0; }
   37.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
   37.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
   37.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
   37.30 +  p.verse { margin-left: 3% }
   37.31 +  pre {
   37.32 +	border: 1pt solid #AEBDCC;
   37.33 +	background-color: #F3F5F7;
   37.34 +	padding: 5pt;
   37.35 +	font-family: courier, monospace;
   37.36 +        font-size: 90%;
   37.37 +        overflow:auto;
   37.38 +  }
   37.39 +  table { border-collapse: collapse; }
   37.40 +  td, th { vertical-align: top;  }
   37.41 +  th.right  { text-align:center;  }
   37.42 +  th.left   { text-align:center;   }
   37.43 +  th.center { text-align:center; }
   37.44 +  td.right  { text-align:right;  }
   37.45 +  td.left   { text-align:left;   }
   37.46 +  td.center { text-align:center; }
   37.47 +  dt { font-weight: bold; }
   37.48 +  div.figure { padding: 0.5em; }
   37.49 +  div.figure p { text-align: center; }
   37.50 +  textarea { overflow-x: auto; }
   37.51 +  .linenr { font-size:smaller }
   37.52 +  .code-highlighted {background-color:#ffff00;}
   37.53 +  .org-info-js_info-navigation { border-style:none; }
   37.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
   37.55 +                               white-space:nowrap; }
   37.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
   37.57 +                                 font-weight:bold; }
   37.58 +  /*]]>*/-->
   37.59 +</style>
   37.60 +<link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
   37.61 +<script type="text/javascript">
   37.62 +<!--/*--><![CDATA[/*><!--*/
   37.63 + function CodeHighlightOn(elem, id)
   37.64 + {
   37.65 +   var target = document.getElementById(id);
   37.66 +   if(null != target) {
   37.67 +     elem.cacheClassElem = elem.className;
   37.68 +     elem.cacheClassTarget = target.className;
   37.69 +     target.className = "code-highlighted";
   37.70 +     elem.className   = "code-highlighted";
   37.71 +   }
   37.72 + }
   37.73 + function CodeHighlightOff(elem, id)
   37.74 + {
   37.75 +   var target = document.getElementById(id);
   37.76 +   if(elem.cacheClassElem)
   37.77 +     elem.className = elem.cacheClassElem;
   37.78 +   if(elem.cacheClassTarget)
   37.79 +     target.className = elem.cacheClassTarget;
   37.80 + }
   37.81 +/*]]>*///-->
   37.82 +</script>
   37.83 +<script type="text/javascript" src="../MathJax/MathJax.js">
   37.84 +<!--/*--><![CDATA[/*><!--*/
   37.85 +    MathJax.Hub.Config({
   37.86 +        // Only one of the two following lines, depending on user settings
   37.87 +        // First allows browser-native MathML display, second forces HTML/CSS
   37.88 +            config: ["MMLorHTML.js"], jax: ["input/TeX"],
   37.89 +        //  jax: ["input/TeX", "output/HTML-CSS"],
   37.90 +        extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js",
   37.91 +                     "TeX/noUndefined.js"],
   37.92 +        tex2jax: {
   37.93 +            inlineMath: [ ["\\(","\\)"] ],
   37.94 +            displayMath: [ ['$$','$$'], ["\\[","\\]"], ["\\begin{displaymath}","\\end{displaymath}"] ],
   37.95 +            skipTags: ["script","noscript","style","textarea","pre","code"],
   37.96 +            ignoreClass: "tex2jax_ignore",
   37.97 +            processEscapes: false,
   37.98 +            processEnvironments: true,
   37.99 +            preview: "TeX"
  37.100 +        },
  37.101 +        showProcessingMessages: true,
  37.102 +        displayAlign: "left",
  37.103 +        displayIndent: "2em",
  37.104 +
  37.105 +        "HTML-CSS": {
  37.106 +             scale: 100,
  37.107 +             availableFonts: ["STIX","TeX"],
  37.108 +             preferredFont: "TeX",
  37.109 +             webFont: "TeX",
  37.110 +             imageFont: "TeX",
  37.111 +             showMathMenu: true,
  37.112 +        },
  37.113 +        MMLorHTML: {
  37.114 +             prefer: {
  37.115 +                 MSIE:    "MML",
  37.116 +                 Firefox: "MML",
  37.117 +                 Opera:   "HTML",
  37.118 +                 other:   "HTML"
  37.119 +             }
  37.120 +        }
  37.121 +    });
  37.122 +/*]]>*///-->
  37.123 +</script>
  37.124 +</head>
  37.125 +<body>
  37.126 +
  37.127 +<div id="content">
  37.128 +
  37.129 +
  37.130 +
  37.131 +<div class="header">
  37.132 +  <div class="float-right">	
  37.133 +    <!-- 
  37.134 +    <form>
  37.135 +      <input type="text"/><input type="submit" value="search the blog &raquo;"/> 
  37.136 +    </form>
  37.137 +    -->
  37.138 +  </div>
  37.139 +
  37.140 +  <h1>aurellem <em>&#x2609;</em></h1>
  37.141 +  <ul class="nav">
  37.142 +    <li><a href="/">read the blog &raquo;</a></li>
  37.143 +    <!-- li><a href="#">learn about us &raquo;</a></li-->
  37.144 +  </ul>
  37.145 +</div>
  37.146 +
  37.147 +<h1 class="title">An Unambiguous Notation for Derivatives</h1>
  37.148 +
  37.149 +
  37.150 +
  37.151 +
  37.152 +
  37.153 +
  37.154 +
  37.155 +<div id="table-of-contents">
  37.156 +<h2>Table of Contents</h2>
  37.157 +<div id="text-table-of-contents">
  37.158 +<ul>
  37.159 +<li><a href="#sec-1">1 Calculus of Infinitesimals </a>
  37.160 +<ul>
  37.161 +<li><a href="#sec-1-1">1.1 Differential Objects </a></li>
  37.162 +<li><a href="#sec-1-2">1.2 Interactions obey the chain rule </a></li>
  37.163 +</ul>
  37.164 +</li>
  37.165 +</ul>
  37.166 +</div>
  37.167 +</div>
  37.168 +
  37.169 +<div id="outline-container-1" class="outline-2">
  37.170 +<h2 id="sec-1"><span class="section-number-2">1</span> Calculus of Infinitesimals </h2>
  37.171 +<div class="outline-text-2" id="text-1">
  37.172 +
  37.173 +
  37.174 +</div>
  37.175 +
  37.176 +<div id="outline-container-1-1" class="outline-3">
  37.177 +<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Differential Objects </h3>
  37.178 +<div class="outline-text-3" id="text-1-1">
  37.179 +
  37.180 +
  37.181 +<p>
  37.182 +A <b>differential object</b> is a pair \([x,\,dx]\) consisting of a variable
  37.183 +and an infinitely small increment of it. Differential objects can
  37.184 +interact with functions, producing a new differential object as a
  37.185 +result; this interaction is for calculating derivatives of functions.
  37.186 +</p>
  37.187 +<p>
  37.188 +Differential objects are for
  37.189 +calculating derivatives of functions: the derivative of \(f\) with
  37.190 +respect to \(x\) 
  37.191 +</p>
  37.192 +<p>
  37.193 +You can &ldquo;apply&rdquo;
  37.194 +functions to differential objects; the result is:
  37.195 +</p>
  37.196 +
  37.197 +
  37.198 +\([x,dx]\xrightarrow{\quad f \quad}[f(x), Df(x)\cdot dx].\)
  37.199 +
  37.200 +<p>
  37.201 +Loosely speaking, the interaction of \(f\) and a differential object
  37.202 +of \(x\) is a differential object of \(f\).
  37.203 +</p>
  37.204 +
  37.205 +</div>
  37.206 +
  37.207 +</div>
  37.208 +
  37.209 +<div id="outline-container-1-2" class="outline-3">
  37.210 +<h3 id="sec-1-2"><span class="section-number-3">1.2</span> Interactions obey the chain rule </h3>
  37.211 +<div class="outline-text-3" id="text-1-2">
  37.212 +
  37.213 +
  37.214 +<p>
  37.215 +The interaction of \(f\) and the differential object \([x, dx]\) is
  37.216 +a differential object \([f(x), Df(x)\cdot dx]\). Because of the rule for
  37.217 +interactions, if you apply another function \(g\), you get the
  37.218 +chain-rule answer you expect:
  37.219 +</p>
  37.220 +
  37.221 +
  37.222 +\([f(x), Df(x)\cdot dx]\xrightarrow{\quad g\quad}\left[g(f(x)),\,
  37.223 +Dg(f(x))\cdot Df(x)\cdot dx\right]\)
  37.224 +
  37.225 +
  37.226 +
  37.227 +
  37.228 +
  37.229 +
  37.230 +
  37.231 +
  37.232 +</div>
  37.233 +</div>
  37.234 +</div>
  37.235 +<div id="postamble">
  37.236 +<p class="date">Date: 2011-08-08 02:49:24 EDT</p>
  37.237 +<p class="author">Author: Dylan Holmes</p>
  37.238 +<p class="creator">Org version 7.6 with Emacs version 23</p>
  37.239 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  37.240 +</div>
  37.241 +</div>
  37.242 +</body>
  37.243 +</html>
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/sicm/deriv.org	Fri Oct 28 00:03:05 2011 -0700
    38.3 @@ -0,0 +1,53 @@
    38.4 +#+TITLE:An Unambiguous Notation for Derivatives
    38.5 +#+author: Dylan Holmes
    38.6 +#+EMAIL: rlm@mit.edu
    38.7 +#+MATHJAX: align:"left" mathml:t path:"../MathJax/MathJax.js"
    38.8 +#+STYLE: <link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
    38.9 +#+OPTIONS:   H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
   38.10 +#+SETUPFILE: ../templates/level-0.org
   38.11 +#+INCLUDE: ../templates/level-0.org
   38.12 +#+BABEL: :noweb yes
   38.13 +
   38.14 +* Calculus of Infinitesimals
   38.15 +** Differential Objects
   38.16 +
   38.17 +A *differential object* is a pair $[x,\,dx]$ consisting of a variable
   38.18 +and an infinitely small increment of it. We want differential objects
   38.19 +to enable us to compute derivatives of functions. 
   38.20 +
   38.21 +Differential objects are for
   38.22 +calculating derivatives of functions: the derivative of $f$ with
   38.23 +respect to $x$ 
   38.24 +
   38.25 +You can \ldquo{}apply\rdquo{}
   38.26 +functions to differential objects; the result is:
   38.27 +
   38.28 +\([x,dx]\xrightarrow{\quad f \quad}[f(x), Df(x)\cdot dx].\)
   38.29 +
   38.30 +Loosely speaking, the interaction of $f$ and a differential object
   38.31 +of $x$ is a differential object of $f$.
   38.32 +
   38.33 +#As a linguistic convention, we'll call this interaction /applying f
   38.34 +#to the differential object/. This is not to be confused with the
   38.35 +#=apply= function in Clojure.
   38.36 +
   38.37 +** Interactions obey the chain rule
   38.38 +
   38.39 +The interaction of $f$ and the differential object $[x, dx]$ is
   38.40 +a differential object $[f(x), Df(x)\cdot dx]$. Because of the rule for
   38.41 +interactions, if you apply another function $g$, you get the
   38.42 +chain-rule answer you expect:
   38.43 +
   38.44 +\([f(x), Df(x)\cdot dx]\xrightarrow{\quad g\quad}\left[g(f(x)),\,
   38.45 +Dg(f(x))\cdot Df(x)\cdot dx\right]\)
   38.46 +
   38.47 +
   38.48 +#+begin_src clojure :tangle deriv.clj
   38.49 +
   38.50 +#+end_src
   38.51 +
   38.52 +#+results:
   38.53 +: nil
   38.54 +
   38.55 +
   38.56 +
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/sicm/notes.html	Fri Oct 28 00:03:05 2011 -0700
    39.3 @@ -0,0 +1,141 @@
    39.4 +<?xml version="1.0" encoding="utf-8"?>
    39.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    39.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    39.7 +<html xmlns="http://www.w3.org/1999/xhtml"
    39.8 +lang="en" xml:lang="en">
    39.9 +<head>
   39.10 +<title>Notes for SICM</title>
   39.11 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
   39.12 +<meta name="generator" content="Org-mode"/>
   39.13 +<meta name="generated" content="2011-08-10 14:07:53 EDT"/>
   39.14 +<meta name="author" content="Robert McIntyre"/>
   39.15 +<meta name="description" content=""/>
   39.16 +<meta name="keywords" content=""/>
   39.17 +<style type="text/css">
   39.18 + <!--/*--><![CDATA[/*><!--*/
   39.19 +  html { font-family: Times, serif; font-size: 12pt; }
   39.20 +  .title  { text-align: center; }
   39.21 +  .todo   { color: red; }
   39.22 +  .done   { color: green; }
   39.23 +  .tag    { background-color: #add8e6; font-weight:normal }
   39.24 +  .target { }
   39.25 +  .timestamp { color: #bebebe; }
   39.26 +  .timestamp-kwd { color: #5f9ea0; }
   39.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
   39.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
   39.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
   39.30 +  p.verse { margin-left: 3% }
   39.31 +  pre {
   39.32 +	border: 1pt solid #AEBDCC;
   39.33 +	background-color: #F3F5F7;
   39.34 +	padding: 5pt;
   39.35 +	font-family: courier, monospace;
   39.36 +        font-size: 90%;
   39.37 +        overflow:auto;
   39.38 +  }
   39.39 +  table { border-collapse: collapse; }
   39.40 +  td, th { vertical-align: top;  }
   39.41 +  th.right  { text-align:center;  }
   39.42 +  th.left   { text-align:center;   }
   39.43 +  th.center { text-align:center; }
   39.44 +  td.right  { text-align:right;  }
   39.45 +  td.left   { text-align:left;   }
   39.46 +  td.center { text-align:center; }
   39.47 +  dt { font-weight: bold; }
   39.48 +  div.figure { padding: 0.5em; }
   39.49 +  div.figure p { text-align: center; }
   39.50 +  textarea { overflow-x: auto; }
   39.51 +  .linenr { font-size:smaller }
   39.52 +  .code-highlighted {background-color:#ffff00;}
   39.53 +  .org-info-js_info-navigation { border-style:none; }
   39.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
   39.55 +                               white-space:nowrap; }
   39.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
   39.57 +                                 font-weight:bold; }
   39.58 +  /*]]>*/-->
   39.59 +</style>
   39.60 +<script type="text/javascript">
   39.61 +<!--/*--><![CDATA[/*><!--*/
   39.62 + function CodeHighlightOn(elem, id)
   39.63 + {
   39.64 +   var target = document.getElementById(id);
   39.65 +   if(null != target) {
   39.66 +     elem.cacheClassElem = elem.className;
   39.67 +     elem.cacheClassTarget = target.className;
   39.68 +     target.className = "code-highlighted";
   39.69 +     elem.className   = "code-highlighted";
   39.70 +   }
   39.71 + }
   39.72 + function CodeHighlightOff(elem, id)
   39.73 + {
   39.74 +   var target = document.getElementById(id);
   39.75 +   if(elem.cacheClassElem)
   39.76 +     elem.className = elem.cacheClassElem;
   39.77 +   if(elem.cacheClassTarget)
   39.78 +     target.className = elem.cacheClassTarget;
   39.79 + }
   39.80 +/*]]>*///-->
   39.81 +</script>
   39.82 +
   39.83 +</head>
   39.84 +<body>
   39.85 +
   39.86 +<div id="content">
   39.87 +
   39.88 +
   39.89 +
   39.90 +<div id="table-of-contents">
   39.91 +<h2>Table of Contents</h2>
   39.92 +<div id="text-table-of-contents">
   39.93 +<ul>
   39.94 +<li><a href="#sec-1">1 Tuples </a></li>
   39.95 +<li><a href="#sec-2">2 Generic arithmetic </a></li>
   39.96 +</ul>
   39.97 +</div>
   39.98 +</div>
   39.99 +
  39.100 +<div id="outline-container-1" class="outline-2">
  39.101 +<h2 id="sec-1"><span class="section-number-2">1</span> Tuples </h2>
  39.102 +<div class="outline-text-2" id="text-1">
  39.103 +
  39.104 +<ul>
  39.105 +<li>Tuples are a new data type: sequences with <i>spin</i>. A tuple can be either spin-up or spin-down.
  39.106 +</li>
  39.107 +<li>A pair of compatible tuples can be <b>contracted</b> into a single number.
  39.108 +<ul>
  39.109 +<li>Tuples are compatible if they have the same length and opposite
  39.110 +    spin, and if their corresponding pairs of items are either both
  39.111 +    numbers or both compatible tuples.
  39.112 +</li>
  39.113 +<li>To contract tuples, take the sum of the products of corresponding
  39.114 +    pairs of items. (To take the product of compatible tuples,
  39.115 +    contract them.)
  39.116 +</li>
  39.117 +</ul>
  39.118 +
  39.119 +</li>
  39.120 +<li>
  39.121 +</li>
  39.122 +</ul>
  39.123 +
  39.124 +
  39.125 +</div>
  39.126 +
  39.127 +</div>
  39.128 +
  39.129 +<div id="outline-container-2" class="outline-2">
  39.130 +<h2 id="sec-2"><span class="section-number-2">2</span> Generic arithmetic </h2>
  39.131 +<div class="outline-text-2" id="text-2">
  39.132 +
  39.133 +
  39.134 +</div>
  39.135 +</div>
  39.136 +<div id="postamble">
  39.137 +<p class="date">Date: 2011-08-10 14:07:53 EDT</p>
  39.138 +<p class="author">Author: Robert McIntyre</p>
  39.139 +<p class="creator">Org version 7.6 with Emacs version 23</p>
  39.140 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  39.141 +</div>
  39.142 +</div>
  39.143 +</body>
  39.144 +</html>
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/sicm/notes.org	Fri Oct 28 00:03:05 2011 -0700
    40.3 @@ -0,0 +1,25 @@
    40.4 +#+TITLE: Notes for SICM
    40.5 +
    40.6 +* Complex numbers
    40.7 +
    40.8 +
    40.9 +* Multidimensional Structures
   40.10 +** Tuples
   40.11 +- Tuples are a new data type: sequences with /spin/. A tuple can be either spin-up or spin-down.
   40.12 +- A pair of compatible tuples can be *contracted* into a single number.
   40.13 +  - Tuples are compatible if they have the same length and opposite
   40.14 +    spin, and if their corresponding pairs of items are either both
   40.15 +    numbers or both compatible tuples.
   40.16 +  - To contract tuples, take the sum of the products of corresponding
   40.17 +    pairs of items. (To take the product of compatible tuples,
   40.18 +    contract them.)
   40.19 +
   40.20 +*Generic Arithmetic:* To multiply two tuples, check to see if they are
   40.21 + compatible. If they are, contract them. If they aren't, multiply each
   40.22 + item of the second tuple by the first tuple.
   40.23 +
   40.24 +To multiply a tuple by a number, multiply each element of the tuple by
   40.25 +the number.
   40.26 +
   40.27 +** Matrices
   40.28 +Uses incanter matrices.
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/sicm/utils.clj	Fri Oct 28 00:03:05 2011 -0700
    41.3 @@ -0,0 +1,496 @@
    41.4 +
    41.5 +(ns sicm.utils)
    41.6 +
    41.7 +(in-ns 'sicm.utils)
    41.8 +
    41.9 +;; Let some objects have spin
   41.10 +
   41.11 +(defprotocol Spinning
   41.12 +  (up? [this])
   41.13 +  (down? [this]))
   41.14 +
   41.15 +(defn spin
   41.16 +  "Returns the spin of the Spinning s, either :up or :down"
   41.17 +  [#^Spinning s]
   41.18 +  (cond (up? s) :up (down? s) :down))
   41.19 +
   41.20 +
   41.21 +;; DEFINITION: A tuple is a sequence with spin
   41.22 +
   41.23 +(deftype Tuple
   41.24 +  [spin coll]
   41.25 +
   41.26 +  clojure.lang.Seqable
   41.27 +  (seq [this] (seq (.coll this)))
   41.28 +
   41.29 +  clojure.lang.Counted
   41.30 +  (count [this] (count (.coll this)))
   41.31 +
   41.32 +  Spinning
   41.33 +  (up? [this] (= ::up (.spin this)))
   41.34 +  (down? [this] (= ::down (.spin this))))
   41.35 +
   41.36 +(defmethod print-method Tuple
   41.37 +  [o w]
   41.38 +  (print-simple
   41.39 +   (if (up? o)
   41.40 +     (str "u" (.coll o))
   41.41 +     (str "d" (vec(.coll o))))
   41.42 +   w))
   41.43 +
   41.44 +(def tuple? #(= (type %) Tuple))
   41.45 +
   41.46 +;; CONSTRUCTORS
   41.47 +
   41.48 +(defn up
   41.49 +  "Create a new up-tuple containing the contents of coll."
   41.50 +  [coll]
   41.51 +  (Tuple. ::up coll))       
   41.52 +
   41.53 +(defn down
   41.54 +  "Create a new down-tuple containing the contents of coll."
   41.55 +  [coll]
   41.56 +  (Tuple. ::down coll))
   41.57 +
   41.58 +(defn same-spin
   41.59 +  "Creates a tuple which has the same spin as tuple and which contains
   41.60 +the contents of coll."
   41.61 +  [tuple coll]
   41.62 +  (if (up? tuple)
   41.63 +    (up coll)
   41.64 +    (down coll)))
   41.65 +
   41.66 +(defn opposite-spin
   41.67 +  "Create a tuple which has opposite spin to tuple and which contains
   41.68 +the contents of coll."
   41.69 +  [tuple coll]
   41.70 +  (if (up? tuple)
   41.71 +    (down coll)
   41.72 +    (up coll)))
   41.73 +(in-ns 'sicm.utils)
   41.74 +(require 'incanter.core) ;; use incanter's fast matrices
   41.75 +
   41.76 +
   41.77 +(defn all-equal? [coll]
   41.78 +  (if (empty? (rest coll)) true
   41.79 +      (and (= (first coll) (second coll))
   41.80 +	   (recur (rest coll)))))
   41.81 +
   41.82 +
   41.83 +(defprotocol Matrix
   41.84 +  (rows [matrix])
   41.85 +  (cols [matrix])
   41.86 +  (diagonal [matrix])
   41.87 +  (trace [matrix])
   41.88 +  (determinant [matrix])
   41.89 +  (transpose [matrix])
   41.90 +  (conjugate [matrix])
   41.91 +)
   41.92 +
   41.93 +(extend-protocol Matrix incanter.Matrix
   41.94 +  (rows [rs] (map down (apply map vector (apply map vector rs))))
   41.95 +  (cols [rs] (map up (apply map vector rs)))
   41.96 +  (diagonal [matrix] (incanter.core/diag matrix) )
   41.97 +  (determinant [matrix] (incanter.core/det matrix))
   41.98 +  (trace [matrix] (incanter.core/trace matrix))
   41.99 +  (transpose [matrix] (incanter.core/trans matrix)))
  41.100 +
  41.101 +(defn count-rows [matrix]
  41.102 +  ((comp count rows) matrix))
  41.103 +
  41.104 +(defn count-cols [matrix]
  41.105 +  ((comp count cols) matrix))
  41.106 +
  41.107 +(defn square? [matrix]
  41.108 +  (= (count-rows matrix) (count-cols matrix)))
  41.109 +
  41.110 +(defn identity-matrix
  41.111 +  "Define a square matrix of size n-by-n with 1s along the diagonal and
  41.112 +  0s everywhere else."
  41.113 +  [n]
  41.114 +  (incanter.core/identity-matrix n))
  41.115 +
  41.116 +
  41.117 +(defn matrix-by-rows
  41.118 +  "Define a matrix by giving its rows."
  41.119 +  [& rows]
  41.120 +  (if
  41.121 +   (not (all-equal? (map count rows)))
  41.122 +   (throw (Exception. "All rows in a matrix must have the same number of elements."))
  41.123 +   (incanter.core/matrix (vec rows))))
  41.124 +
  41.125 +(defn matrix-by-cols
  41.126 +  "Define a matrix by giving its columns"
  41.127 +  [& cols]
  41.128 +  (if (not (all-equal? (map count cols)))
  41.129 +   (throw (Exception. "All columns in a matrix must have the same number of elements."))
  41.130 +   (incanter.core/matrix (vec (apply map vector cols)))))
  41.131 +
  41.132 +(defn identity-matrix
  41.133 +  "Define a square matrix of size n-by-n with 1s along the diagonal and
  41.134 +  0s everywhere else."
  41.135 +  [n]
  41.136 +  (incanter.core/identity-matrix n))
  41.137 +
  41.138 +(in-ns 'sicm.utils)
  41.139 +(use 'clojure.contrib.generic.arithmetic
  41.140 +     'clojure.contrib.generic.collection
  41.141 +     'clojure.contrib.generic.functor
  41.142 +     'clojure.contrib.generic.math-functions)
  41.143 +
  41.144 +(defn numbers?
  41.145 +  "Returns true if all arguments are numbers, else false."
  41.146 +  [& xs]
  41.147 +  (every? number? xs))
  41.148 +
  41.149 +(defn tuple-surgery
  41.150 +  "Applies the function f to the items of tuple and the additional
  41.151 +  arguments, if any. Returns a Tuple of the same type as tuple."
  41.152 +  [tuple f & xs]
  41.153 +  ((if (up? tuple) up down)
  41.154 +   (apply f (seq tuple) xs)))
  41.155 +
  41.156 +
  41.157 +
  41.158 +;;; CONTRACTION collapses two compatible tuples into a number.
  41.159 +
  41.160 +(defn contractible?
  41.161 +  "Returns true if the tuples a and b are compatible for contraction,
  41.162 +  else false. Tuples are compatible if they have the same number of
  41.163 +  components, they have opposite spins, and their elements are
  41.164 +  pairwise-compatible."
  41.165 +  [a b]
  41.166 +  (and
  41.167 +   (isa? (type a) Tuple)
  41.168 +   (isa? (type b) Tuple)
  41.169 +   (= (count a) (count b))
  41.170 +   (not= (spin a) (spin b))
  41.171 +   
  41.172 +   (not-any? false?
  41.173 +	     (map #(or
  41.174 +		    (numbers? %1 %2)
  41.175 +		    (contractible? %1 %2))
  41.176 +		  a b))))
  41.177 +
  41.178 +(defn contract
  41.179 +  "Contracts two tuples, returning the sum of the
  41.180 +  products of the corresponding items. Contraction is recursive on
  41.181 +  nested tuples."
  41.182 +  [a b]
  41.183 +  (if (not (contractible? a b))
  41.184 +    (throw
  41.185 +     (Exception. "Not compatible for contraction."))
  41.186 +    (reduce +
  41.187 +	    (map
  41.188 +	     (fn [x y]
  41.189 +	       (if (numbers? x y)
  41.190 +		 (* x y)
  41.191 +		 (contract x y)))
  41.192 +	     a b))))
  41.193 +
  41.194 +
  41.195 +
  41.196 +
  41.197 +
  41.198 +(defmethod conj Tuple
  41.199 +  [tuple & xs]
  41.200 +  (tuple-surgery tuple #(apply conj % xs)))
  41.201 +
  41.202 +(defmethod fmap Tuple
  41.203 +  [f tuple]
  41.204 +  (tuple-surgery tuple (partial map f)))
  41.205 +
  41.206 +
  41.207 +
  41.208 +;; TODO: define Scalar, and add it to the hierarchy above Number and Complex
  41.209 +
  41.210 +					
  41.211 +(defmethod * [Tuple Tuple]             ; tuple*tuple
  41.212 +  [a b]
  41.213 +  (if (contractible? a b)
  41.214 +    (contract a b)
  41.215 +    (map (partial * a) b)))
  41.216 +
  41.217 +
  41.218 +(defmethod * [java.lang.Number Tuple]  ;; scalar *  tuple
  41.219 +  [a x] (fmap (partial * a) x))
  41.220 +
  41.221 +(defmethod * [Tuple java.lang.Number]
  41.222 +  [x a] (* a x))
  41.223 +
  41.224 +(defmethod * [java.lang.Number incanter.Matrix] ;; scalar *  matrix
  41.225 +  [x M] (incanter.core/mult x M))
  41.226 +
  41.227 +(defmethod * [incanter.Matrix java.lang.Number]
  41.228 +  [M x] (* x M))
  41.229 +
  41.230 +(defmethod * [incanter.Matrix incanter.Matrix] ;; matrix * matrix
  41.231 +  [M1 M2]
  41.232 +  (incanter.core/mmult M1 M2))
  41.233 +
  41.234 +(defmethod * [incanter.Matrix Tuple] ;; matrix * tuple
  41.235 +  [M v]
  41.236 +  (if (and (apply numbers? v) (up? v)) 
  41.237 +    (* M (matrix-by-cols v))
  41.238 +    (throw (Exception. "Currently, you can only multiply a matrix by a tuple of *numbers*"))
  41.239 +    ))
  41.240 +
  41.241 +(defmethod * [Tuple incanter.Matrix] ;; tuple * Matrix
  41.242 +  [v M]
  41.243 +  (if (and (apply numbers? v) (down? v))
  41.244 +    (* (matrix-by-rows v) M)
  41.245 +    (throw (Exception. "Currently, you can only multiply a matrix by a tuple of *numbers*"))
  41.246 +    ))
  41.247 +
  41.248 +
  41.249 +(defmethod exp incanter.Matrix
  41.250 +  [M]
  41.251 +  (incanter.core/exp M))
  41.252 +
  41.253 +
  41.254 +(in-ns 'sicm.utils)
  41.255 +(use 'clojure.contrib.seq
  41.256 +     'clojure.contrib.generic.arithmetic
  41.257 +     'clojure.contrib.generic.collection
  41.258 +     'clojure.contrib.generic.math-functions)
  41.259 +
  41.260 +;;∂
  41.261 +
  41.262 +;; DEFINITION : Differential Term
  41.263 +
  41.264 +;; A quantity with infinitesimal components, e.g. x, dxdy, 4dydz. The
  41.265 +;; coefficient of the quantity is returned by the 'coefficient' method,
  41.266 +;; while the sequence of differential parameters is returned by the
  41.267 +;; method 'partials'.
  41.268 +
  41.269 +;; Instead of using (potentially ambiguous) letters to denote
  41.270 +;; differential parameters (dx,dy,dz), we use integers. So, dxdz becomes [0 2].
  41.271 +
  41.272 +;; The coefficient can be any arithmetic object; the
  41.273 +;; partials must be a nonrepeating sorted sequence of nonnegative
  41.274 +;; integers.
  41.275 +
  41.276 +(deftype DifferentialTerm [coefficient partials])
  41.277 +
  41.278 +(defn differential-term
  41.279 +  "Make a differential term from a  coefficient and list of partials."
  41.280 +  [coefficient partials]
  41.281 +  (if (and (coll? partials) (every? #(and (integer? %) (not(neg? %))) partials)) 
  41.282 +    (DifferentialTerm. coefficient (set partials))
  41.283 +    (throw (java.lang.IllegalArgumentException. "Partials must be a collection of integers."))))
  41.284 +
  41.285 +
  41.286 +;; DEFINITION : Differential Sequence
  41.287 +;; A differential sequence is a sequence of differential terms, all with different partials.
  41.288 +;; Internally, it is a map from the partials of each term to their coefficients.
  41.289 +
  41.290 +(deftype DifferentialSeq
  41.291 +  [terms]
  41.292 +  ;;clojure.lang.IPersistentMap
  41.293 +  clojure.lang.Associative
  41.294 +  (assoc [this key val]
  41.295 +    (DifferentialSeq.
  41.296 +     (cons (differential-term val key) terms)))
  41.297 +  (cons [this x]
  41.298 +	(DifferentialSeq. (cons x terms)))
  41.299 +  (containsKey [this key]
  41.300 +	       (not(nil? (find-first #(= (.partials %) key) terms))))
  41.301 +  (count [this] (count (.terms this)))
  41.302 +  (empty [this] (DifferentialSeq. []))
  41.303 +  (entryAt [this key]
  41.304 +	   ((juxt #(.partials %) #(.coefficient %))
  41.305 +	    (find-first #(= (.partials %) key) terms)))
  41.306 +  (seq [this] (seq (.terms this))))
  41.307 +
  41.308 +(def differential? #(= (type %) DifferentialSeq))
  41.309 +
  41.310 +(defn zeroth-order?
  41.311 +  "Returns true if the differential sequence has at most a constant term."
  41.312 +  [dseq]
  41.313 +  (and
  41.314 +   (differential? dseq)
  41.315 +   (every?
  41.316 +    #(= #{} %)
  41.317 +    (keys (.terms dseq)))))
  41.318 +
  41.319 +(defmethod fmap DifferentialSeq
  41.320 +  [f dseq]
  41.321 +  (DifferentialSeq.
  41.322 +   (fmap f (.terms dseq))))
  41.323 +
  41.324 +
  41.325 +
  41.326 +
  41.327 +;; BUILDING DIFFERENTIAL OBJECTS
  41.328 +
  41.329 +(defn differential-seq
  41.330 +    "Define a differential sequence by specifying an alternating
  41.331 +sequence of coefficients and lists of partials."
  41.332 +  ([coefficient partials]
  41.333 +     (DifferentialSeq. {(set partials) coefficient}))
  41.334 +  ([coefficient partials & cps]
  41.335 +     (if (odd? (count cps))
  41.336 +       (throw (Exception. "differential-seq requires an even number of terms."))
  41.337 +       (DifferentialSeq.
  41.338 +	(reduce
  41.339 +	 #(assoc %1 (set (second %2)) (first %2))
  41.340 +	 {(set partials) coefficient}
  41.341 +	 (partition 2 cps))))))
  41.342 +  
  41.343 +
  41.344 +
  41.345 +(defn big-part
  41.346 +  "Returns the part of the differential sequence that is finite,
  41.347 +  i.e. not infinitely small. If the sequence is zeroth-order, returns
  41.348 +  the coefficient of the zeroth-order term instead. "
  41.349 +  [dseq]
  41.350 +  (if (zeroth-order? dseq) (get (.terms dseq) #{})
  41.351 +      (let [m (.terms dseq)
  41.352 +	    keys (sort-by count (keys m))
  41.353 +	    smallest-var (last (last keys))]
  41.354 +	(DifferentialSeq.
  41.355 +	 (reduce
  41.356 +	  #(assoc %1 (first %2) (second %2))
  41.357 +	  {}
  41.358 +	  (remove #((first %) smallest-var) m))))))
  41.359 +
  41.360 +
  41.361 +(defn small-part
  41.362 +  "Returns the part of the differential sequence that infinitely
  41.363 +  small. If the sequence is zeroth-order, returns zero."
  41.364 +  [dseq]
  41.365 +  (if (zeroth-order? dseq) 0
  41.366 +      (let [m (.terms dseq)
  41.367 +	    keys (sort-by count (keys m))
  41.368 +	    smallest-var (last (last keys))]
  41.369 +	(DifferentialSeq.
  41.370 +	 (reduce
  41.371 +	  #(assoc %1 (first %2) (second %2)) {}
  41.372 +	  (filter #((first %) smallest-var) m))))))
  41.373 +
  41.374 +
  41.375 +
  41.376 +(defn cartesian-product [set1 set2]
  41.377 +  (reduce concat
  41.378 +	  (for [x set1]
  41.379 +	    (for [y set2]
  41.380 +	      [x y]))))
  41.381 +
  41.382 +(defn nth-subset [n]
  41.383 +  (if (zero? n) []
  41.384 +      (let [lg2 #(/ (log %) (log 2))
  41.385 +	    k (int(java.lang.Math/floor (lg2 n)))
  41.386 +	    ]
  41.387 +	(cons k
  41.388 +	 (nth-subset  (- n (pow 2 k)))))))
  41.389 +    
  41.390 +(def all-partials
  41.391 +     (lazy-seq (map nth-subset (range))))
  41.392 +
  41.393 +
  41.394 +(defn differential-multiply
  41.395 +  "Multiply two differential sequences. The square of any differential
  41.396 +  variable is zero since differential variables are infinitesimally
  41.397 +  small."
  41.398 +  [dseq1 dseq2]
  41.399 +  (DifferentialSeq.
  41.400 +   (reduce
  41.401 +    (fn [m [[vars1 coeff1] [vars2 coeff2]]]
  41.402 +      (if (not (empty? (clojure.set/intersection vars1 vars2)))
  41.403 +	m
  41.404 +	(assoc m (clojure.set/union vars1 vars2) (* coeff1 coeff2))))
  41.405 +    {}
  41.406 +    (cartesian-product (.terms dseq1) (.terms dseq2)))))
  41.407 +
  41.408 +
  41.409 +
  41.410 +(defmethod * [DifferentialSeq DifferentialSeq]
  41.411 +  [dseq1 dseq2]
  41.412 +   (differential-multiply dseq1 dseq2))
  41.413 +
  41.414 +(defmethod + [DifferentialSeq DifferentialSeq]
  41.415 +  [dseq1 dseq2]
  41.416 +  (DifferentialSeq.
  41.417 +   (merge-with + (.terms dseq1) (.terms dseq2))))
  41.418 +
  41.419 +(defmethod * [java.lang.Number DifferentialSeq]
  41.420 +  [x dseq]
  41.421 +  (fmap (partial * x) dseq))
  41.422 +
  41.423 +(defmethod * [DifferentialSeq java.lang.Number]
  41.424 +  [dseq x]
  41.425 +  (fmap (partial * x) dseq))
  41.426 +
  41.427 +(defmethod + [java.lang.Number DifferentialSeq]
  41.428 +  [x dseq]
  41.429 +  (+ (differential-seq x []) dseq))
  41.430 +(defmethod + [DifferentialSeq java.lang.Number]
  41.431 +  [dseq x]
  41.432 +  (+ dseq (differential-seq x [])))
  41.433 +
  41.434 +(defmethod - DifferentialSeq
  41.435 +  [x]
  41.436 +  (fmap - x))
  41.437 +
  41.438 +
  41.439 +;; DERIVATIVES
  41.440 +
  41.441 +	      
  41.442 +
  41.443 +(defn linear-approximator
  41.444 +  "Returns an operator that linearly approximates the given function."
  41.445 +  ([f df|dx]
  41.446 +      (fn [x]
  41.447 +	(let [big-part (big-part x)
  41.448 +	      small-part (small-part x)]
  41.449 +	  ;; f(x+dx) ~= f(x) + f'(x)dx
  41.450 +	  (+ (f big-part)
  41.451 +	     (* (df|dx big-part) small-part)
  41.452 +	  ))))
  41.453 +     
  41.454 +  ([f df|dx df|dy]
  41.455 +     (fn [x y]
  41.456 +       (let [X (big-part x)
  41.457 +	     Y (big-part y)
  41.458 +	     DX (small-part x)
  41.459 +	     DY (small-part y)]
  41.460 +	 (+ (f X Y)
  41.461 +	    (* DX (f df|dx X Y))
  41.462 +	    (* DY (f df|dy X Y)))))))
  41.463 +
  41.464 +
  41.465 +
  41.466 +
  41.467 +
  41.468 +(defn D[f]
  41.469 +  (fn[x] (f (+ x (differential-seq  1 [0] 1 [1] 1 [2])))))
  41.470 +  
  41.471 +(defn d[partials f]
  41.472 +  (fn [x]
  41.473 +    (get 
  41.474 +     (.terms ((D f)x))
  41.475 +     (set partials)
  41.476 +     0
  41.477 +    )))
  41.478 +
  41.479 +(defmethod exp DifferentialSeq [x]
  41.480 +	   ((linear-approximator exp exp) x))
  41.481 +
  41.482 +(defmethod sin DifferentialSeq
  41.483 +  [x]
  41.484 +  ((linear-approximator sin cos) x))
  41.485 +
  41.486 +(defmethod cos DifferentialSeq
  41.487 +  [x]
  41.488 +  ((linear-approximator cos #(- (sin %))) x))
  41.489 +
  41.490 +(defmethod log DifferentialSeq
  41.491 +  [x]
  41.492 +  ((linear-approximator log (fn [x] (/ x)) ) x))
  41.493 +
  41.494 +(defmethod / [DifferentialSeq DifferentialSeq]
  41.495 +  [x y]
  41.496 +  ((linear-approximator /
  41.497 +			(fn [x y] (/ 1 y))
  41.498 +			(fn [x y] (- (/ x (* y y)))))
  41.499 +   x y))
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/sicm/utils.html	Fri Oct 28 00:03:05 2011 -0700
    42.3 @@ -0,0 +1,702 @@
    42.4 +<?xml version="1.0" encoding="utf-8"?>
    42.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    42.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    42.7 +<html xmlns="http://www.w3.org/1999/xhtml"
    42.8 +lang="en" xml:lang="en">
    42.9 +<head>
   42.10 +<title>Building a Classical Mechanics Library in Clojure</title>
   42.11 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
   42.12 +<meta name="generator" content="Org-mode"/>
   42.13 +<meta name="generated" content="2011-08-11 04:10:36 EDT"/>
   42.14 +<meta name="author" content="Dylan Holmes"/>
   42.15 +<meta name="description" content=""/>
   42.16 +<meta name="keywords" content=""/>
   42.17 +<style type="text/css">
   42.18 + <!--/*--><![CDATA[/*><!--*/
   42.19 +  html { font-family: Times, serif; font-size: 12pt; }
   42.20 +  .title  { text-align: center; }
   42.21 +  .todo   { color: red; }
   42.22 +  .done   { color: green; }
   42.23 +  .tag    { background-color: #add8e6; font-weight:normal }
   42.24 +  .target { }
   42.25 +  .timestamp { color: #bebebe; }
   42.26 +  .timestamp-kwd { color: #5f9ea0; }
   42.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
   42.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
   42.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
   42.30 +  p.verse { margin-left: 3% }
   42.31 +  pre {
   42.32 +	border: 1pt solid #AEBDCC;
   42.33 +	background-color: #F3F5F7;
   42.34 +	padding: 5pt;
   42.35 +	font-family: courier, monospace;
   42.36 +        font-size: 90%;
   42.37 +        overflow:auto;
   42.38 +  }
   42.39 +  table { border-collapse: collapse; }
   42.40 +  td, th { vertical-align: top;  }
   42.41 +  th.right  { text-align:center;  }
   42.42 +  th.left   { text-align:center;   }
   42.43 +  th.center { text-align:center; }
   42.44 +  td.right  { text-align:right;  }
   42.45 +  td.left   { text-align:left;   }
   42.46 +  td.center { text-align:center; }
   42.47 +  dt { font-weight: bold; }
   42.48 +  div.figure { padding: 0.5em; }
   42.49 +  div.figure p { text-align: center; }
   42.50 +  textarea { overflow-x: auto; }
   42.51 +  .linenr { font-size:smaller }
   42.52 +  .code-highlighted {background-color:#ffff00;}
   42.53 +  .org-info-js_info-navigation { border-style:none; }
   42.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
   42.55 +                               white-space:nowrap; }
   42.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
   42.57 +                                 font-weight:bold; }
   42.58 +  /*]]>*/-->
   42.59 +</style>
   42.60 +<link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
   42.61 +<script type="text/javascript">
   42.62 +<!--/*--><![CDATA[/*><!--*/
   42.63 + function CodeHighlightOn(elem, id)
   42.64 + {
   42.65 +   var target = document.getElementById(id);
   42.66 +   if(null != target) {
   42.67 +     elem.cacheClassElem = elem.className;
   42.68 +     elem.cacheClassTarget = target.className;
   42.69 +     target.className = "code-highlighted";
   42.70 +     elem.className   = "code-highlighted";
   42.71 +   }
   42.72 + }
   42.73 + function CodeHighlightOff(elem, id)
   42.74 + {
   42.75 +   var target = document.getElementById(id);
   42.76 +   if(elem.cacheClassElem)
   42.77 +     elem.className = elem.cacheClassElem;
   42.78 +   if(elem.cacheClassTarget)
   42.79 +     target.className = elem.cacheClassTarget;
   42.80 + }
   42.81 +/*]]>*///-->
   42.82 +</script>
   42.83 +
   42.84 +</head>
   42.85 +<body>
   42.86 +
   42.87 +<div id="content">
   42.88 +
   42.89 +
   42.90 +
   42.91 +<div class="header">
   42.92 +  <div class="float-right">	
   42.93 +    <!-- 
   42.94 +    <form>
   42.95 +      <input type="text"/><input type="submit" value="search the blog &raquo;"/> 
   42.96 +    </form>
   42.97 +    -->
   42.98 +  </div>
   42.99 +
  42.100 +  <h1>aurellem <em>&#x2609;</em></h1>
  42.101 +  <ul class="nav">
  42.102 +    <li><a href="/">read the blog &raquo;</a></li>
  42.103 +    <!-- li><a href="#">learn about us &raquo;</a></li-->
  42.104 +  </ul>
  42.105 +</div>
  42.106 +
  42.107 +<h1 class="title">Building a Classical Mechanics Library in Clojure</h1>
  42.108 +
  42.109 +
  42.110 +
  42.111 +
  42.112 +
  42.113 +
  42.114 +
  42.115 +<div id="table-of-contents">
  42.116 +<h2>Table of Contents</h2>
  42.117 +<div id="text-table-of-contents">
  42.118 +<ul>
  42.119 +<li><a href="#sec-1">1 Useful data types </a>
  42.120 +<ul>
  42.121 +<li><a href="#sec-1-1">1.1 Complex numbers </a></li>
  42.122 +<li><a href="#sec-1-2">1.2 Power series </a></li>
  42.123 +<li><a href="#sec-1-3">1.3 Tuples and tensors </a>
  42.124 +<ul>
  42.125 +<li><a href="#sec-1-3-1">1.3.1 Tuples are &ldquo;sequences with spin&rdquo; </a></li>
  42.126 +<li><a href="#sec-1-3-2">1.3.2 Matrices </a></li>
  42.127 +</ul>
  42.128 +</li>
  42.129 +<li><a href="#sec-1-4">1.4 Generic Operations </a></li>
  42.130 +</ul>
  42.131 +</li>
  42.132 +<li><a href="#sec-2">2 Operators and Differentiation </a>
  42.133 +<ul>
  42.134 +<li><a href="#sec-2-1">2.1 Operators </a></li>
  42.135 +<li><a href="#sec-2-2">2.2 Differential Terms and Sequences </a></li>
  42.136 +</ul>
  42.137 +</li>
  42.138 +</ul>
  42.139 +</div>
  42.140 +</div>
  42.141 +
  42.142 +<div id="outline-container-1" class="outline-2">
  42.143 +<h2 id="sec-1"><span class="section-number-2">1</span> Useful data types </h2>
  42.144 +<div class="outline-text-2" id="text-1">
  42.145 +
  42.146 +
  42.147 +
  42.148 +</div>
  42.149 +
  42.150 +<div id="outline-container-1-1" class="outline-3">
  42.151 +<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Complex numbers </h3>
  42.152 +<div class="outline-text-3" id="text-1-1">
  42.153 +
  42.154 +
  42.155 +</div>
  42.156 +
  42.157 +</div>
  42.158 +
  42.159 +<div id="outline-container-1-2" class="outline-3">
  42.160 +<h3 id="sec-1-2"><span class="section-number-3">1.2</span> Power series </h3>
  42.161 +<div class="outline-text-3" id="text-1-2">
  42.162 +
  42.163 +
  42.164 +</div>
  42.165 +
  42.166 +</div>
  42.167 +
  42.168 +<div id="outline-container-1-3" class="outline-3">
  42.169 +<h3 id="sec-1-3"><span class="section-number-3">1.3</span> Tuples and tensors </h3>
  42.170 +<div class="outline-text-3" id="text-1-3">
  42.171 +
  42.172 +
  42.173 +
  42.174 +</div>
  42.175 +
  42.176 +<div id="outline-container-1-3-1" class="outline-4">
  42.177 +<h4 id="sec-1-3-1"><span class="section-number-4">1.3.1</span> Tuples are &ldquo;sequences with spin&rdquo; </h4>
  42.178 +<div class="outline-text-4" id="text-1-3-1">
  42.179 +
  42.180 +
  42.181 +
  42.182 +
  42.183 +
  42.184 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  42.185 +
  42.186 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">Let some objects have spin</span>
  42.187 +
  42.188 +(<span style="color: #f0dfaf; font-weight: bold;">defprotocol</span> <span style="color: #f0dfaf;">Spinning</span>
  42.189 +  (up? [this])
  42.190 +  (down? [this]))
  42.191 +
  42.192 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">spin</span>
  42.193 +  <span style="color: #8fb28f;">"Returns the spin of the Spinning s, either :up or :down"</span>
  42.194 +  [<span style="color: #dfdfbf; font-weight: bold;">#^Spinning</span> s]
  42.195 +  (<span style="color: #f0dfaf; font-weight: bold;">cond</span> (up? s) <span style="color: #8cd0d3;">:up</span> (down? s) <span style="color: #8cd0d3;">:down</span>))
  42.196 +
  42.197 +
  42.198 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">DEFINITION: A tuple is a sequence with spin</span>
  42.199 +
  42.200 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">Tuple</span>
  42.201 +  [spin coll]
  42.202 +
  42.203 +  clojure.lang.Seqable
  42.204 +  (<span style="color: #8cd0d3;">seq</span> [this] (<span style="color: #8cd0d3;">seq</span> (.coll this)))
  42.205 +
  42.206 +  clojure.lang.Counted
  42.207 +  (<span style="color: #8cd0d3;">count</span> [this] (<span style="color: #8cd0d3;">count</span> (.coll this)))
  42.208 +
  42.209 +  Spinning
  42.210 +  (up? [this] (<span style="color: #8cd0d3;">=</span> <span style="color: #8cd0d3;">::up</span> (.spin this)))
  42.211 +  (down? [this] (<span style="color: #8cd0d3;">=</span> <span style="color: #8cd0d3;">::down</span> (.spin this))))
  42.212 +
  42.213 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">print-method</span> Tuple
  42.214 +  [o w]
  42.215 +  (<span style="color: #8cd0d3;">print-simple</span>
  42.216 +   (<span style="color: #f0dfaf; font-weight: bold;">if</span> (up? o)
  42.217 +     (<span style="color: #8cd0d3;">str</span> <span style="color: #cc9393;">"u"</span> (.coll o))
  42.218 +     (<span style="color: #8cd0d3;">str</span> <span style="color: #cc9393;">"d"</span> (<span style="color: #8cd0d3;">vec</span>(.coll o))))
  42.219 +   w))
  42.220 +
  42.221 +
  42.222 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">CONSTRUCTORS</span>
  42.223 +
  42.224 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">up</span>
  42.225 +  <span style="color: #8fb28f;">"Create a new up-tuple containing the contents of coll."</span>
  42.226 +  [coll]
  42.227 +  (Tuple. <span style="color: #8cd0d3;">::up</span> coll))       
  42.228 +
  42.229 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">down</span>
  42.230 +  <span style="color: #8fb28f;">"Create a new down-tuple containing the contents of coll."</span>
  42.231 +  [coll]
  42.232 +  (Tuple. <span style="color: #8cd0d3;">::down</span> coll))
  42.233 +</pre>
  42.234 +
  42.235 +
  42.236 +
  42.237 +
  42.238 +
  42.239 +
  42.240 +</div>
  42.241 +
  42.242 +</div>
  42.243 +
  42.244 +<div id="outline-container-1-3-2" class="outline-4">
  42.245 +<h4 id="sec-1-3-2"><span class="section-number-4">1.3.2</span> Matrices </h4>
  42.246 +<div class="outline-text-4" id="text-1-3-2">
  42.247 +
  42.248 +
  42.249 +
  42.250 +
  42.251 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  42.252 +(<span style="color: #8cd0d3;">require</span> 'incanter.core) <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">use incanter's fast matrices</span>
  42.253 +
  42.254 +
  42.255 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">all-equal?</span> [coll]
  42.256 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">empty?</span> (<span style="color: #8cd0d3;">rest</span> coll)) true
  42.257 +      (<span style="color: #f0dfaf; font-weight: bold;">and</span> (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">first</span> coll) (<span style="color: #8cd0d3;">second</span> coll))
  42.258 +           (<span style="color: #f0dfaf; font-weight: bold;">recur</span> (<span style="color: #8cd0d3;">rest</span> coll)))))
  42.259 +
  42.260 +
  42.261 +(<span style="color: #f0dfaf; font-weight: bold;">defprotocol</span> <span style="color: #f0dfaf;">Matrix</span>
  42.262 +  (rows [matrix])
  42.263 +  (cols [matrix])
  42.264 +  (diagonal [matrix])
  42.265 +  (trace [matrix])
  42.266 +  (determinant [matrix])
  42.267 +  (transpose [matrix])
  42.268 +  (conjugate [matrix])
  42.269 +)
  42.270 +
  42.271 +(<span style="color: #8cd0d3;">extend-protocol</span> Matrix incanter.Matrix
  42.272 +  (rows [rs] (<span style="color: #8cd0d3;">map</span> down (<span style="color: #8cd0d3;">apply</span> map vector (<span style="color: #8cd0d3;">apply</span> map vector rs))))
  42.273 +  (cols [rs] (<span style="color: #8cd0d3;">map</span> up (<span style="color: #8cd0d3;">apply</span> map vector rs)))
  42.274 +  (diagonal [matrix] (incanter.core/diag matrix) )
  42.275 +  (determinant [matrix] (incanter.core/det matrix))
  42.276 +  (trace [matrix] (incanter.core/trace matrix))
  42.277 +  (transpose [matrix] (incanter.core/trans matrix)))
  42.278 +
  42.279 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">count-rows</span> [matrix]
  42.280 +  ((<span style="color: #8cd0d3;">comp</span> count rows) matrix))
  42.281 +
  42.282 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">count-cols</span> [matrix]
  42.283 +  ((<span style="color: #8cd0d3;">comp</span> count cols) matrix))
  42.284 +
  42.285 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">square?</span> [matrix]
  42.286 +  (<span style="color: #8cd0d3;">=</span> (count-rows matrix) (count-cols matrix)))
  42.287 +
  42.288 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">identity-matrix</span>
  42.289 +  <span style="color: #8fb28f;">"Define a square matrix of size n-by-n with 1s along the diagonal and</span>
  42.290 +<span style="color: #8fb28f;">  0s everywhere else."</span>
  42.291 +  [n]
  42.292 +  (incanter.core/identity-matrix n))
  42.293 +
  42.294 +
  42.295 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">matrix-by-rows</span>
  42.296 +  <span style="color: #8fb28f;">"Define a matrix by giving its rows."</span>
  42.297 +  [&amp; rows]
  42.298 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span>
  42.299 +   (<span style="color: #8cd0d3;">not</span> (all-equal? (<span style="color: #8cd0d3;">map</span> count rows)))
  42.300 +   (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"All rows in a matrix must have the same number of elements."</span>))
  42.301 +   (incanter.core/matrix (<span style="color: #8cd0d3;">vec</span> rows))))
  42.302 +
  42.303 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">matrix-by-cols</span>
  42.304 +  <span style="color: #8fb28f;">"Define a matrix by giving its columns"</span>
  42.305 +  [&amp; cols]
  42.306 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not</span> (all-equal? (<span style="color: #8cd0d3;">map</span> count cols)))
  42.307 +   (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"All columns in a matrix must have the same number of elements."</span>))
  42.308 +   (incanter.core/matrix (<span style="color: #8cd0d3;">vec</span> (<span style="color: #8cd0d3;">apply</span> map vector cols)))))
  42.309 +
  42.310 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">identity-matrix</span>
  42.311 +  <span style="color: #8fb28f;">"Define a square matrix of size n-by-n with 1s along the diagonal and</span>
  42.312 +<span style="color: #8fb28f;">  0s everywhere else."</span>
  42.313 +  [n]
  42.314 +  (incanter.core/identity-matrix n))
  42.315 +
  42.316 +</pre>
  42.317 +
  42.318 +
  42.319 +
  42.320 +
  42.321 +</div>
  42.322 +</div>
  42.323 +
  42.324 +</div>
  42.325 +
  42.326 +<div id="outline-container-1-4" class="outline-3">
  42.327 +<h3 id="sec-1-4"><span class="section-number-3">1.4</span> Generic Operations </h3>
  42.328 +<div class="outline-text-3" id="text-1-4">
  42.329 +
  42.330 +
  42.331 +
  42.332 +
  42.333 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  42.334 +(<span style="color: #8cd0d3;">use</span> 'clojure.contrib.generic.arithmetic
  42.335 +     'clojure.contrib.generic.collection
  42.336 +     'clojure.contrib.generic.functor
  42.337 +     'clojure.contrib.generic.math-functions)
  42.338 +
  42.339 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">numbers?</span>
  42.340 +  <span style="color: #8fb28f;">"Returns true if all arguments are numbers, else false."</span>
  42.341 +  [&amp; xs]
  42.342 +  (<span style="color: #8cd0d3;">every?</span> number? xs))
  42.343 +
  42.344 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">tuple-surgery</span>
  42.345 +  <span style="color: #8fb28f;">"Applies the function f to the items of tuple and the additional</span>
  42.346 +<span style="color: #8fb28f;">  arguments, if any. Returns a Tuple of the same type as tuple."</span>
  42.347 +  [tuple f &amp; xs]
  42.348 +  ((<span style="color: #f0dfaf; font-weight: bold;">if</span> (up? tuple) up down)
  42.349 +   (<span style="color: #8cd0d3;">apply</span> f (<span style="color: #8cd0d3;">seq</span> tuple) xs)))
  42.350 +
  42.351 +
  42.352 +
  42.353 +<span style="color: #708070;">;;; </span><span style="color: #7f9f7f;">CONTRACTION collapses two compatible tuples into a number.</span>
  42.354 +
  42.355 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">contractible?</span>
  42.356 +  <span style="color: #8fb28f;">"Returns true if the tuples a and b are compatible for contraction,</span>
  42.357 +<span style="color: #8fb28f;">  else false. Tuples are compatible if they have the same number of</span>
  42.358 +<span style="color: #8fb28f;">  components, they have opposite spins, and their elements are</span>
  42.359 +<span style="color: #8fb28f;">  pairwise-compatible."</span>
  42.360 +  [a b]
  42.361 +  (<span style="color: #f0dfaf; font-weight: bold;">and</span>
  42.362 +   (<span style="color: #8cd0d3;">isa?</span> (<span style="color: #8cd0d3;">type</span> a) Tuple)
  42.363 +   (<span style="color: #8cd0d3;">isa?</span> (<span style="color: #8cd0d3;">type</span> b) Tuple)
  42.364 +   (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">count</span> a) (<span style="color: #8cd0d3;">count</span> b))
  42.365 +   (<span style="color: #8cd0d3;">not=</span> (spin a) (spin b))
  42.366 +   
  42.367 +   (<span style="color: #8cd0d3;">not-any?</span> false?
  42.368 +             (<span style="color: #8cd0d3;">map</span> #(<span style="color: #f0dfaf; font-weight: bold;">or</span>
  42.369 +                    (numbers? %1 %2)
  42.370 +                    (contractible? %1 %2))
  42.371 +                  a b))))
  42.372 +
  42.373 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">contract</span>
  42.374 +  <span style="color: #8fb28f;">"Contracts two tuples, returning the sum of the</span>
  42.375 +<span style="color: #8fb28f;">  products of the corresponding items. Contraction is recursive on</span>
  42.376 +<span style="color: #8fb28f;">  nested tuples."</span>
  42.377 +  [a b]
  42.378 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not</span> (contractible? a b))
  42.379 +    (<span style="color: #f0dfaf; font-weight: bold;">throw</span>
  42.380 +     (Exception. <span style="color: #cc9393;">"Not compatible for contraction."</span>))
  42.381 +    (<span style="color: #8cd0d3;">reduce</span> +
  42.382 +            (<span style="color: #8cd0d3;">map</span>
  42.383 +             (<span style="color: #8cd0d3;">fn</span> [x y]
  42.384 +               (<span style="color: #f0dfaf; font-weight: bold;">if</span> (numbers? x y)
  42.385 +                 (<span style="color: #8cd0d3;">*</span> x y)
  42.386 +                 (contract x y)))
  42.387 +             a b))))
  42.388 +
  42.389 +
  42.390 +
  42.391 +
  42.392 +
  42.393 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">conj</span> Tuple
  42.394 +  [tuple &amp; xs]
  42.395 +  (tuple-surgery tuple #(<span style="color: #8cd0d3;">apply</span> conj % xs)))
  42.396 +
  42.397 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">fmap</span> Tuple
  42.398 +  [f tuple]
  42.399 +  (tuple-surgery tuple (<span style="color: #8cd0d3;">partial</span> map f)))
  42.400 +
  42.401 +
  42.402 +
  42.403 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">TODO: define Scalar, and add it to the hierarchy above Number and Complex</span>
  42.404 +
  42.405 +                                        
  42.406 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [Tuple Tuple]             <span style="color: #708070;">; </span><span style="color: #7f9f7f;">tuple*tuple</span>
  42.407 +  [a b]
  42.408 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (contractible? a b)
  42.409 +    (contract a b)
  42.410 +    (<span style="color: #8cd0d3;">map</span> (<span style="color: #8cd0d3;">partial</span> * a) b)))
  42.411 +
  42.412 +
  42.413 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [java.lang.Number Tuple]  <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">scalar *  tuple</span>
  42.414 +  [a x] (fmap (<span style="color: #8cd0d3;">partial</span> * a) x))
  42.415 +
  42.416 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [Tuple java.lang.Number]
  42.417 +  [x a] (<span style="color: #8cd0d3;">*</span> a x))
  42.418 +
  42.419 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [java.lang.Number incanter.Matrix] <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">scalar *  matrix</span>
  42.420 +  [x M] (incanter.core/mult x M))
  42.421 +
  42.422 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [incanter.Matrix java.lang.Number]
  42.423 +  [M x] (<span style="color: #8cd0d3;">*</span> x M))
  42.424 +
  42.425 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [incanter.Matrix incanter.Matrix] <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">matrix * matrix</span>
  42.426 +  [M1 M2]
  42.427 +  (incanter.core/mmult M1 M2))
  42.428 +
  42.429 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [incanter.Matrix Tuple] <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">matrix * tuple</span>
  42.430 +  [M v]
  42.431 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #f0dfaf; font-weight: bold;">and</span> (<span style="color: #8cd0d3;">apply</span> numbers? v) (up? v)) 
  42.432 +    (<span style="color: #8cd0d3;">*</span> M (matrix-by-cols v))
  42.433 +    (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"Currently, you can only multiply a matrix by a tuple of *numbers*"</span>))
  42.434 +    ))
  42.435 +
  42.436 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [Tuple incanter.Matrix] <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">tuple * Matrix</span>
  42.437 +  [v M]
  42.438 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #f0dfaf; font-weight: bold;">and</span> (<span style="color: #8cd0d3;">apply</span> numbers? v) (down? v))
  42.439 +    (<span style="color: #8cd0d3;">*</span> (matrix-by-rows v) M)
  42.440 +    (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"Currently, you can only multiply a matrix by a tuple of *numbers*"</span>))
  42.441 +    ))
  42.442 +
  42.443 +
  42.444 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">exp</span> incanter.Matrix
  42.445 +  [M]
  42.446 +  (incanter.core/exp M))
  42.447 +
  42.448 +</pre>
  42.449 +
  42.450 +
  42.451 +
  42.452 +
  42.453 +</div>
  42.454 +</div>
  42.455 +
  42.456 +</div>
  42.457 +
  42.458 +<div id="outline-container-2" class="outline-2">
  42.459 +<h2 id="sec-2"><span class="section-number-2">2</span> Operators and Differentiation </h2>
  42.460 +<div class="outline-text-2" id="text-2">
  42.461 +
  42.462 +
  42.463 +
  42.464 +
  42.465 +</div>
  42.466 +
  42.467 +<div id="outline-container-2-1" class="outline-3">
  42.468 +<h3 id="sec-2-1"><span class="section-number-3">2.1</span> Operators </h3>
  42.469 +<div class="outline-text-3" id="text-2-1">
  42.470 +
  42.471 +
  42.472 +</div>
  42.473 +
  42.474 +</div>
  42.475 +
  42.476 +<div id="outline-container-2-2" class="outline-3">
  42.477 +<h3 id="sec-2-2"><span class="section-number-3">2.2</span> Differential Terms and Sequences </h3>
  42.478 +<div class="outline-text-3" id="text-2-2">
  42.479 +
  42.480 +
  42.481 +
  42.482 +
  42.483 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
  42.484 +(<span style="color: #8cd0d3;">use</span> 'clojure.contrib.seq
  42.485 +     'clojure.contrib.generic.arithmetic
  42.486 +     'clojure.contrib.generic.collection
  42.487 +     'clojure.contrib.generic.math-functions)
  42.488 +
  42.489 +<span style="color: #708070;">;;</span><span style="color: #7f9f7f;">&#8706;</span>
  42.490 +
  42.491 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">DEFINITION : Differential Term</span>
  42.492 +
  42.493 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">A quantity with infinitesimal components, e.g. x, dxdy, 4dydz. The</span>
  42.494 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">coefficient of the quantity is returned by the 'coefficient' method,</span>
  42.495 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">while the sequence of differential parameters is returned by the</span>
  42.496 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">method 'partials'.</span>
  42.497 +
  42.498 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">Instead of using (potentially ambiguous) letters to denote</span>
  42.499 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">differential parameters (dx,dy,dz), we use integers. So, dxdz becomes [0 2].</span>
  42.500 +
  42.501 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">The coefficient can be any arithmetic object; the</span>
  42.502 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">partials must be a nonrepeating sorted sequence of nonnegative</span>
  42.503 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">integers.</span>
  42.504 +
  42.505 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">DifferentialTerm</span> [coefficient partials])
  42.506 +
  42.507 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-term</span>
  42.508 +  <span style="color: #8fb28f;">"Make a differential term given pairs of coefficients and partials."</span>
  42.509 +  [coefficient partials]
  42.510 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #f0dfaf; font-weight: bold;">and</span> (<span style="color: #8cd0d3;">coll?</span> partials) (<span style="color: #8cd0d3;">every?</span> #(<span style="color: #f0dfaf; font-weight: bold;">and</span> (<span style="color: #8cd0d3;">integer?</span> %) (<span style="color: #8cd0d3;">not</span>(<span style="color: #8cd0d3;">neg?</span> %))) partials)) 
  42.511 +    (DifferentialTerm. coefficient (<span style="color: #8cd0d3;">set</span> partials))
  42.512 +    (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (java.lang.IllegalArgumentException. <span style="color: #cc9393;">"Partials must be a collection of integers."</span>))))
  42.513 +
  42.514 +
  42.515 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">DEFINITION : Differential Sequence</span>
  42.516 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">A differential sequence is a sequence of differential terms, all with different partials.</span>
  42.517 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">Internally, it is a map from the partials of each term to their coefficients.</span>
  42.518 +
  42.519 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">DifferentialSeq</span>
  42.520 +  [terms]
  42.521 +  <span style="color: #708070;">;;</span><span style="color: #7f9f7f;">clojure.lang.IPersistentMap</span>
  42.522 +  clojure.lang.Associative
  42.523 +  (<span style="color: #8cd0d3;">assoc</span> [this key val]
  42.524 +    (DifferentialSeq.
  42.525 +     (<span style="color: #8cd0d3;">cons</span> (differential-term val key) terms)))
  42.526 +  (<span style="color: #8cd0d3;">cons</span> [this x]
  42.527 +        (DifferentialSeq. (<span style="color: #8cd0d3;">cons</span> x terms)))
  42.528 +  (containsKey [this key]
  42.529 +               (<span style="color: #8cd0d3;">not</span>(<span style="color: #8cd0d3;">nil?</span> (find-first #(<span style="color: #8cd0d3;">=</span> (.partials %) key) terms))))
  42.530 +  (<span style="color: #8cd0d3;">count</span> [this] (<span style="color: #8cd0d3;">count</span> (.terms this)))
  42.531 +  (<span style="color: #8cd0d3;">empty</span> [this] (DifferentialSeq. []))
  42.532 +  (entryAt [this key]
  42.533 +           ((<span style="color: #8cd0d3;">juxt</span> #(.partials %) #(.coefficient %))
  42.534 +            (find-first #(<span style="color: #8cd0d3;">=</span> (.partials %) key) terms)))
  42.535 +  (<span style="color: #8cd0d3;">seq</span> [this] (<span style="color: #8cd0d3;">seq</span> (.terms this))))
  42.536 +
  42.537 +
  42.538 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">fmap</span> DifferentialSeq
  42.539 +  [f dseq]
  42.540 +  (DifferentialSeq. (fmap f (.terms dseq))))
  42.541 +
  42.542 +
  42.543 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">BUILDING DIFFERENTIAL OBJECTS</span>
  42.544 +
  42.545 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-seq</span>
  42.546 +    <span style="color: #8fb28f;">"Define a differential sequence by specifying coefficient/partials</span>
  42.547 +<span style="color: #8fb28f;">pairs, which are used to create differential terms to populate the</span>
  42.548 +<span style="color: #8fb28f;">sequence."</span>
  42.549 +  ([coefficient partials]
  42.550 +     (DifferentialSeq. {(<span style="color: #8cd0d3;">set</span> partials) coefficient}))
  42.551 +  ([coefficient partials &amp; cps]
  42.552 +     (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">odd?</span> (<span style="color: #8cd0d3;">count</span> cps))
  42.553 +       (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"differential-seq requires an even number of terms."</span>))
  42.554 +       (DifferentialSeq.
  42.555 +        (<span style="color: #8cd0d3;">reduce</span>
  42.556 +         #(<span style="color: #8cd0d3;">assoc</span> %1 (<span style="color: #8cd0d3;">set</span> (<span style="color: #8cd0d3;">second</span> %2)) (<span style="color: #8cd0d3;">first</span> %2))
  42.557 +         {(<span style="color: #8cd0d3;">set</span> partials) coefficient}
  42.558 +         (<span style="color: #8cd0d3;">partition</span> 2 cps))))))
  42.559 +  
  42.560 +
  42.561 +
  42.562 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">big-part</span>
  42.563 +  <span style="color: #8fb28f;">"Returns the part of the differential sequence that is finite,</span>
  42.564 +<span style="color: #8fb28f;">  i.e. not infinitely small, as a differential sequence. If given a</span>
  42.565 +<span style="color: #8fb28f;">  non-differential object, returns that object."</span>
  42.566 +  [dseq]
  42.567 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not=</span> (<span style="color: #8cd0d3;">type</span> dseq) DifferentialSeq) dseq
  42.568 +      (<span style="color: #f0dfaf; font-weight: bold;">let</span> [m (.terms dseq)
  42.569 +            keys (<span style="color: #8cd0d3;">sort-by</span> count (<span style="color: #8cd0d3;">keys</span> m))
  42.570 +            smallest-var (<span style="color: #8cd0d3;">last</span> (<span style="color: #8cd0d3;">last</span> keys))]
  42.571 +        (DifferentialSeq.
  42.572 +         (<span style="color: #8cd0d3;">reduce</span>
  42.573 +          #(<span style="color: #8cd0d3;">assoc</span> %1 (<span style="color: #8cd0d3;">first</span> %2) (<span style="color: #8cd0d3;">second</span> %2))
  42.574 +          {}
  42.575 +          (<span style="color: #8cd0d3;">remove</span> #((<span style="color: #8cd0d3;">first</span> %) smallest-var) m))))))
  42.576 +
  42.577 +
  42.578 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">small-part</span>
  42.579 +  <span style="color: #8fb28f;">"Returns the part of the differential sequence that infinitely</span>
  42.580 +<span style="color: #8fb28f;">  small, as a differential sequence. If given a non-differential</span>
  42.581 +<span style="color: #8fb28f;">  object, returns that object."</span>
  42.582 +  [dseq]
  42.583 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not=</span> (<span style="color: #8cd0d3;">type</span> dseq) DifferentialSeq) 0
  42.584 +      (<span style="color: #f0dfaf; font-weight: bold;">let</span> [m (.terms dseq)
  42.585 +            keys (<span style="color: #8cd0d3;">sort-by</span> count (<span style="color: #8cd0d3;">keys</span> m))
  42.586 +            smallest-var (<span style="color: #8cd0d3;">last</span> (<span style="color: #8cd0d3;">last</span> keys))]
  42.587 +        (DifferentialSeq.
  42.588 +         (<span style="color: #8cd0d3;">reduce</span>
  42.589 +          #(<span style="color: #8cd0d3;">assoc</span> %1 (<span style="color: #8cd0d3;">first</span> %2) (<span style="color: #8cd0d3;">second</span> %2)) {}
  42.590 +          (<span style="color: #8cd0d3;">filter</span> #((<span style="color: #8cd0d3;">first</span> %) smallest-var) m))))))
  42.591 +
  42.592 +
  42.593 +
  42.594 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">cartesian-product</span> [set1 set2]
  42.595 +  (<span style="color: #8cd0d3;">reduce</span> concat
  42.596 +          (<span style="color: #f0dfaf; font-weight: bold;">for</span> [x set1]
  42.597 +            (<span style="color: #f0dfaf; font-weight: bold;">for</span> [y set2]
  42.598 +              [x y]))))
  42.599 +
  42.600 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-multiply</span>
  42.601 +  <span style="color: #8fb28f;">"Multiply two differential sequences. The square of any differential</span>
  42.602 +<span style="color: #8fb28f;">  variable is zero since differential variables are infinitesimally</span>
  42.603 +<span style="color: #8fb28f;">  small."</span>
  42.604 +  [dseq1 dseq2]
  42.605 +  (DifferentialSeq.
  42.606 +   (<span style="color: #8cd0d3;">reduce</span>
  42.607 +    (<span style="color: #8cd0d3;">fn</span> [m [[vars1 coeff1] [vars2 coeff2]]]
  42.608 +      (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not</span> (<span style="color: #8cd0d3;">empty?</span> (clojure.set/<span style="color: #dfdfbf; font-weight: bold;">intersection</span> vars1 vars2)))
  42.609 +        m
  42.610 +        (<span style="color: #8cd0d3;">assoc</span> m (clojure.set/<span style="color: #dfdfbf; font-weight: bold;">union</span> vars1 vars2) (<span style="color: #8cd0d3;">*</span> coeff1 coeff2))))
  42.611 +    {}
  42.612 +    (cartesian-product (.terms dseq1) (.terms dseq2)))))
  42.613 +
  42.614 +
  42.615 +
  42.616 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [DifferentialSeq DifferentialSeq]
  42.617 +  [dseq1 dseq2]
  42.618 +   (differential-multiply dseq1 dseq2))
  42.619 +
  42.620 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">+</span> [DifferentialSeq DifferentialSeq]
  42.621 +  [dseq1 dseq2]
  42.622 +  (DifferentialSeq.
  42.623 +   (<span style="color: #8cd0d3;">merge-with</span> + (.terms dseq1) (.terms dseq2))))
  42.624 +
  42.625 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [java.lang.Number DifferentialSeq]
  42.626 +  [x dseq]
  42.627 +  (fmap (<span style="color: #8cd0d3;">partial</span> * x) dseq))
  42.628 +
  42.629 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [DifferentialSeq java.lang.Number]
  42.630 +  [dseq x]
  42.631 +  (fmap (<span style="color: #8cd0d3;">partial</span> * x) dseq))
  42.632 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">DERIVATIVES</span>
  42.633 +
  42.634 +
  42.635 +
  42.636 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">linear-approximator</span>
  42.637 +  <span style="color: #8fb28f;">"Returns an operator that linearly approximates the given function."</span>
  42.638 +  ([f df|dx]
  42.639 +     (<span style="color: #8cd0d3;">fn</span> [x]
  42.640 +       (<span style="color: #f0dfaf; font-weight: bold;">let</span> [big-part (big-part x)
  42.641 +             small-part (small-part x)]
  42.642 +         (<span style="color: #8cd0d3;">+</span> (fmap f big-part)
  42.643 +            (<span style="color: #8cd0d3;">*</span> (fmap df|dx big-part) small-part)))))
  42.644 +  ([f df|dx df|dy]
  42.645 +     (<span style="color: #8cd0d3;">fn</span> [x y]
  42.646 +       (<span style="color: #f0dfaf; font-weight: bold;">let</span> [X (big-part x)
  42.647 +             Y (big-part y)
  42.648 +             DX (small-part x)
  42.649 +             DY (small-part y)]
  42.650 +         (<span style="color: #8cd0d3;">+</span> (f X Y)
  42.651 +            (<span style="color: #8cd0d3;">+</span> (<span style="color: #8cd0d3;">*</span> DX (df|dx X Y))
  42.652 +               (<span style="color: #8cd0d3;">*</span> DY (df|dy X Y)))))))
  42.653 +  )
  42.654 +
  42.655 +
  42.656 +
  42.657 +
  42.658 +
  42.659 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">D</span>[f]
  42.660 +  (<span style="color: #8cd0d3;">fn</span>[x]
  42.661 +    (f (differential-seq x [] 1 [0]))))
  42.662 +
  42.663 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">d</span>[f partials]
  42.664 +  (<span style="color: #8cd0d3;">fn</span> [x]
  42.665 +    (<span style="color: #8cd0d3;">get</span> 
  42.666 +     (.terms ((D f)x))
  42.667 +     (<span style="color: #8cd0d3;">set</span> partials)
  42.668 +     0
  42.669 +    )))
  42.670 +
  42.671 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">exp</span> DifferentialSeq [x]
  42.672 +           ((linear-approximator exp exp) x))
  42.673 +
  42.674 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">sin</span> DifferentialSeq
  42.675 +  [x]
  42.676 +  ((linear-approximator sin cos) x))
  42.677 +
  42.678 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">cos</span> DifferentialSeq
  42.679 +  [x]
  42.680 +  ((linear-approximator cos #(<span style="color: #8cd0d3;">-</span> (sin %))) x))
  42.681 +     
  42.682 +
  42.683 +
  42.684 +</pre>
  42.685 +
  42.686 +
  42.687 +
  42.688 +
  42.689 +
  42.690 +
  42.691 +
  42.692 +
  42.693 +
  42.694 +</div>
  42.695 +</div>
  42.696 +</div>
  42.697 +<div id="postamble">
  42.698 +<p class="date">Date: 2011-08-11 04:10:36 EDT</p>
  42.699 +<p class="author">Author: Dylan Holmes</p>
  42.700 +<p class="creator">Org version 7.6 with Emacs version 23</p>
  42.701 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  42.702 +</div>
  42.703 +</div>
  42.704 +</body>
  42.705 +</html>
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/sicm/utils.org	Fri Oct 28 00:03:05 2011 -0700
    43.3 @@ -0,0 +1,690 @@
    43.4 +#+TITLE: Building a Classical Mechanics Library in Clojure
    43.5 +#+author: Dylan Holmes
    43.6 +#+EMAIL:     rlm@mit.edu
    43.7 +#+MATHJAX: align:"left" mathml:t path:"../MathJax/MathJax.js"
    43.8 +#+STYLE: <link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
    43.9 +#+OPTIONS:   H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
   43.10 +#+SETUPFILE: ../templates/level-0.org
   43.11 +#+INCLUDE: ../templates/level-0.org
   43.12 +#+BABEL: :noweb yes :results silent
   43.13 +
   43.14 +* Useful data types
   43.15 +
   43.16 +** Complex numbers
   43.17 +
   43.18 +** Power series
   43.19 +
   43.20 +** Tuples and tensors
   43.21 +
   43.22 +*** Tuples are \ldquo{}sequences with spin\rdquo{}
   43.23 +
   43.24 +#+srcname: tuples
   43.25 +#+begin_src clojure
   43.26 +(in-ns 'sicm.utils)
   43.27 +
   43.28 +;; Let some objects have spin
   43.29 +
   43.30 +(defprotocol Spinning
   43.31 +  (up? [this])
   43.32 +  (down? [this]))
   43.33 +
   43.34 +(defn spin
   43.35 +  "Returns the spin of the Spinning s, either :up or :down"
   43.36 +  [#^Spinning s]
   43.37 +  (cond (up? s) :up (down? s) :down))
   43.38 +
   43.39 +
   43.40 +;; DEFINITION: A tuple is a sequence with spin
   43.41 +
   43.42 +(deftype Tuple
   43.43 +  [spin coll]
   43.44 +
   43.45 +  clojure.lang.Seqable
   43.46 +  (seq [this] (seq (.coll this)))
   43.47 +
   43.48 +  clojure.lang.Counted
   43.49 +  (count [this] (count (.coll this)))
   43.50 +
   43.51 +  Spinning
   43.52 +  (up? [this] (= ::up (.spin this)))
   43.53 +  (down? [this] (= ::down (.spin this))))
   43.54 +
   43.55 +(defmethod print-method Tuple
   43.56 +  [o w]
   43.57 +  (print-simple
   43.58 +   (if (up? o)
   43.59 +     (str "u" (.coll o))
   43.60 +     (str "d" (vec(.coll o))))
   43.61 +   w))
   43.62 +
   43.63 +(def tuple? #(= (type %) Tuple))
   43.64 +
   43.65 +;; CONSTRUCTORS
   43.66 +
   43.67 +(defn up
   43.68 +  "Create a new up-tuple containing the contents of coll."
   43.69 +  [coll]
   43.70 +  (Tuple. ::up coll))       
   43.71 +
   43.72 +(defn down
   43.73 +  "Create a new down-tuple containing the contents of coll."
   43.74 +  [coll]
   43.75 +  (Tuple. ::down coll))
   43.76 +
   43.77 +(defn same-spin
   43.78 +  "Creates a tuple which has the same spin as tuple and which contains
   43.79 +the contents of coll."
   43.80 +  [tuple coll]
   43.81 +  (if (up? tuple)
   43.82 +    (up coll)
   43.83 +    (down coll)))
   43.84 +
   43.85 +(defn opposite-spin
   43.86 +  "Create a tuple which has opposite spin to tuple and which contains
   43.87 +the contents of coll."
   43.88 +  [tuple coll]
   43.89 +  (if (up? tuple)
   43.90 +    (down coll)
   43.91 +    (up coll)))
   43.92 +#+end_src
   43.93 +
   43.94 +
   43.95 +
   43.96 +*** Matrices
   43.97 +#+srcname:matrices
   43.98 +#+begin_src clojure
   43.99 +(in-ns 'sicm.utils)
  43.100 +(require 'incanter.core) ;; use incanter's fast matrices
  43.101 +
  43.102 +
  43.103 +(defn all-equal? [coll]
  43.104 +  (if (empty? (rest coll)) true
  43.105 +      (and (= (first coll) (second coll))
  43.106 +	   (recur (rest coll)))))
  43.107 +
  43.108 +
  43.109 +(defprotocol Matrix
  43.110 +  (rows [matrix])
  43.111 +  (cols [matrix])
  43.112 +  (diagonal [matrix])
  43.113 +  (trace [matrix])
  43.114 +  (determinant [matrix])
  43.115 +  (transpose [matrix])
  43.116 +  (conjugate [matrix])
  43.117 +)
  43.118 +
  43.119 +(extend-protocol Matrix incanter.Matrix
  43.120 +  (rows [rs] (map down (apply map vector (apply map vector rs))))
  43.121 +  (cols [rs] (map up (apply map vector rs)))
  43.122 +  (diagonal [matrix] (incanter.core/diag matrix) )
  43.123 +  (determinant [matrix] (incanter.core/det matrix))
  43.124 +  (trace [matrix] (incanter.core/trace matrix))
  43.125 +  (transpose [matrix] (incanter.core/trans matrix)))
  43.126 +
  43.127 +(defn count-rows [matrix]
  43.128 +  ((comp count rows) matrix))
  43.129 +
  43.130 +(defn count-cols [matrix]
  43.131 +  ((comp count cols) matrix))
  43.132 +
  43.133 +(defn square? [matrix]
  43.134 +  (= (count-rows matrix) (count-cols matrix)))
  43.135 +
  43.136 +(defn identity-matrix
  43.137 +  "Define a square matrix of size n-by-n with 1s along the diagonal and
  43.138 +  0s everywhere else."
  43.139 +  [n]
  43.140 +  (incanter.core/identity-matrix n))
  43.141 +
  43.142 +
  43.143 +(defn matrix-by-rows
  43.144 +  "Define a matrix by giving its rows."
  43.145 +  [& rows]
  43.146 +  (if
  43.147 +   (not (all-equal? (map count rows)))
  43.148 +   (throw (Exception. "All rows in a matrix must have the same number of elements."))
  43.149 +   (incanter.core/matrix (vec rows))))
  43.150 +
  43.151 +(defn matrix-by-cols
  43.152 +  "Define a matrix by giving its columns"
  43.153 +  [& cols]
  43.154 +  (if (not (all-equal? (map count cols)))
  43.155 +   (throw (Exception. "All columns in a matrix must have the same number of elements."))
  43.156 +   (incanter.core/matrix (vec (apply map vector cols)))))
  43.157 +
  43.158 +(defn identity-matrix
  43.159 +  "Define a square matrix of size n-by-n with 1s along the diagonal and
  43.160 +  0s everywhere else."
  43.161 +  [n]
  43.162 +  (incanter.core/identity-matrix n))
  43.163 +
  43.164 +#+end_src
  43.165 +
  43.166 +** Generic Operations
  43.167 +#+srcname:arith-tuple
  43.168 +#+begin_src clojure
  43.169 +(in-ns 'sicm.utils)
  43.170 +(use 'clojure.contrib.generic.arithmetic
  43.171 +     'clojure.contrib.generic.collection
  43.172 +     'clojure.contrib.generic.functor
  43.173 +     'clojure.contrib.generic.math-functions)
  43.174 +
  43.175 +(defn numbers?
  43.176 +  "Returns true if all arguments are numbers, else false."
  43.177 +  [& xs]
  43.178 +  (every? number? xs))
  43.179 +
  43.180 +(defn tuple-surgery
  43.181 +  "Applies the function f to the items of tuple and the additional
  43.182 +  arguments, if any. Returns a Tuple of the same type as tuple."
  43.183 +  [tuple f & xs]
  43.184 +  ((if (up? tuple) up down)
  43.185 +   (apply f (seq tuple) xs)))
  43.186 +
  43.187 +
  43.188 +
  43.189 +;;; CONTRACTION collapses two compatible tuples into a number.
  43.190 +
  43.191 +(defn contractible?
  43.192 +  "Returns true if the tuples a and b are compatible for contraction,
  43.193 +  else false. Tuples are compatible if they have the same number of
  43.194 +  components, they have opposite spins, and their elements are
  43.195 +  pairwise-compatible."
  43.196 +  [a b]
  43.197 +  (and
  43.198 +   (isa? (type a) Tuple)
  43.199 +   (isa? (type b) Tuple)
  43.200 +   (= (count a) (count b))
  43.201 +   (not= (spin a) (spin b))
  43.202 +   
  43.203 +   (not-any? false?
  43.204 +	     (map #(or
  43.205 +		    (numbers? %1 %2)
  43.206 +		    (contractible? %1 %2))
  43.207 +		  a b))))
  43.208 +
  43.209 +(defn contract
  43.210 +  "Contracts two tuples, returning the sum of the
  43.211 +  products of the corresponding items. Contraction is recursive on
  43.212 +  nested tuples."
  43.213 +  [a b]
  43.214 +  (if (not (contractible? a b))
  43.215 +    (throw
  43.216 +     (Exception. "Not compatible for contraction."))
  43.217 +    (reduce +
  43.218 +	    (map
  43.219 +	     (fn [x y]
  43.220 +	       (if (numbers? x y)
  43.221 +		 (* x y)
  43.222 +		 (contract x y)))
  43.223 +	     a b))))
  43.224 +
  43.225 +
  43.226 +
  43.227 +
  43.228 +
  43.229 +(defmethod conj Tuple
  43.230 +  [tuple & xs]
  43.231 +  (tuple-surgery tuple #(apply conj % xs)))
  43.232 +
  43.233 +(defmethod fmap Tuple
  43.234 +  [f tuple]
  43.235 +  (tuple-surgery tuple (partial map f)))
  43.236 +
  43.237 +
  43.238 +
  43.239 +;; TODO: define Scalar, and add it to the hierarchy above Number and Complex
  43.240 +
  43.241 +					
  43.242 +(defmethod * [Tuple Tuple]             ; tuple*tuple
  43.243 +  [a b]
  43.244 +  (if (contractible? a b)
  43.245 +    (contract a b)
  43.246 +    (map (partial * a) b)))
  43.247 +
  43.248 +
  43.249 +(defmethod * [java.lang.Number Tuple]  ;; scalar *  tuple
  43.250 +  [a x] (fmap (partial * a) x))
  43.251 +
  43.252 +(defmethod * [Tuple java.lang.Number]
  43.253 +  [x a] (* a x))
  43.254 +
  43.255 +(defmethod * [java.lang.Number incanter.Matrix] ;; scalar *  matrix
  43.256 +  [x M] (incanter.core/mult x M))
  43.257 +
  43.258 +(defmethod * [incanter.Matrix java.lang.Number]
  43.259 +  [M x] (* x M))
  43.260 +
  43.261 +(defmethod * [incanter.Matrix incanter.Matrix] ;; matrix * matrix
  43.262 +  [M1 M2]
  43.263 +  (incanter.core/mmult M1 M2))
  43.264 +
  43.265 +(defmethod * [incanter.Matrix Tuple] ;; matrix * tuple
  43.266 +  [M v]
  43.267 +  (if (and (apply numbers? v) (up? v)) 
  43.268 +    (* M (matrix-by-cols v))
  43.269 +    (throw (Exception. "Currently, you can only multiply a matrix by a tuple of *numbers*"))
  43.270 +    ))
  43.271 +
  43.272 +(defmethod * [Tuple incanter.Matrix] ;; tuple * Matrix
  43.273 +  [v M]
  43.274 +  (if (and (apply numbers? v) (down? v))
  43.275 +    (* (matrix-by-rows v) M)
  43.276 +    (throw (Exception. "Currently, you can only multiply a matrix by a tuple of *numbers*"))
  43.277 +    ))
  43.278 +
  43.279 +
  43.280 +(defmethod exp incanter.Matrix
  43.281 +  [M]
  43.282 +  (incanter.core/exp M))
  43.283 +
  43.284 +#+end_src
  43.285 +
  43.286 +* Operators and Differentiation
  43.287 +** Operators
  43.288 +#+scrname: operators
  43.289 +#+begin_src clojure
  43.290 +(in-ns 'sicm.utils)
  43.291 +(use 'clojure.contrib.seq
  43.292 +     'clojure.contrib.generic.arithmetic
  43.293 +     'clojure.contrib.generic.collection
  43.294 +     'clojure.contrib.generic.math-functions)
  43.295 +
  43.296 +(defmethod + [clojure.lang.IFn clojure.lang.IFn]
  43.297 +	   [f g]
  43.298 +	   (fn [& args]
  43.299 +	     (+ (apply f args) (apply g args))))
  43.300 +
  43.301 +(defmethod * [clojure.lang.IFn clojure.lang.IFn]
  43.302 +	   [f g]
  43.303 +	   (fn [& args]
  43.304 +	     (* (apply f args) (apply g args))))
  43.305 +
  43.306 +(defmethod / [clojure.lang.IFn java.lang.Number]
  43.307 +  [f x]
  43.308 +  (fn [& args]
  43.309 +    (/ (apply f args) x)))
  43.310 +
  43.311 +
  43.312 +(defmethod - [clojure.lang.IFn]
  43.313 +  [f]
  43.314 +  (fn [& args]
  43.315 +    (- (apply f args))))
  43.316 +
  43.317 +(defmethod - [clojure.lang.IFn clojure.lang.IFn]
  43.318 +  [f g]
  43.319 +  (fn [& args]
  43.320 +    (- (apply f args) (apply g args))))
  43.321 +
  43.322 +(defmethod pow [clojure.lang.IFn java.lang.Number]
  43.323 +  [f x]
  43.324 +  (fn [& args]
  43.325 +    (pow (apply f args) x)))
  43.326 +
  43.327 +
  43.328 +(defmethod + [java.lang.Number clojure.lang.IFn]
  43.329 +	   [x f]
  43.330 +	   (fn [& args]
  43.331 +	     (+ x (apply f args))))
  43.332 +
  43.333 +(defmethod * [java.lang.Number clojure.lang.IFn]
  43.334 +	   [x f]
  43.335 +	   (fn [& args]
  43.336 +	     (* x (apply f args))))
  43.337 +
  43.338 +(defmethod * [clojure.lang.IFn java.lang.Number]
  43.339 +	   [f x]
  43.340 +	   (* x f))
  43.341 +(defmethod + [clojure.lang.IFn java.lang.Number]
  43.342 +	   [f x]
  43.343 +	   (+ x f))
  43.344 +
  43.345 +#+end_src
  43.346 +
  43.347 +** Differential Terms and Sequences
  43.348 +#+srcname: differential
  43.349 +#+begin_src clojure
  43.350 +(in-ns 'sicm.utils)
  43.351 +(use 'clojure.contrib.seq
  43.352 +     'clojure.contrib.generic.arithmetic
  43.353 +     'clojure.contrib.generic.collection
  43.354 +     'clojure.contrib.generic.math-functions)
  43.355 +
  43.356 +;;∂
  43.357 +
  43.358 +;; DEFINITION : Differential Term
  43.359 +
  43.360 +;; A quantity with infinitesimal components, e.g. x, dxdy, 4dydz. The
  43.361 +;; coefficient of the quantity is returned by the 'coefficient' method,
  43.362 +;; while the sequence of differential parameters is returned by the
  43.363 +;; method 'partials'.
  43.364 +
  43.365 +;; Instead of using (potentially ambiguous) letters to denote
  43.366 +;; differential parameters (dx,dy,dz), we use integers. So, dxdz becomes [0 2].
  43.367 +
  43.368 +;; The coefficient can be any arithmetic object; the
  43.369 +;; partials must be a nonrepeating sorted sequence of nonnegative
  43.370 +;; integers.
  43.371 +
  43.372 +;; (deftype DifferentialTerm [coefficient partials])
  43.373 +
  43.374 +;; (defn differential-term
  43.375 +;;   "Make a differential term from a  coefficient and list of partials."
  43.376 +;;   [coefficient partials]
  43.377 +;;   (if (and (coll? partials) (every? #(and (integer? %) (not(neg? %))) partials)) 
  43.378 +;;     (DifferentialTerm. coefficient (set partials))
  43.379 +;;     (throw (java.lang.IllegalArgumentException. "Partials must be a collection of integers."))))
  43.380 +
  43.381 +
  43.382 +;; DEFINITION : Differential Sequence
  43.383 +;; A differential sequence is a sequence of differential terms, all with different partials.
  43.384 +;; Internally, it is a map from the partials of each term to their coefficients.
  43.385 +
  43.386 +(deftype DifferentialSeq
  43.387 +  [terms]
  43.388 +  ;;clojure.lang.IPersistentMap
  43.389 +  clojure.lang.Associative
  43.390 +  (assoc [this key val]
  43.391 +    (DifferentialSeq.
  43.392 +     (cons (differential-term val key) terms)))
  43.393 +  (cons [this x]
  43.394 +	(DifferentialSeq. (cons x terms)))
  43.395 +  (containsKey [this key]
  43.396 +	       (not(nil? (find-first #(= (.partials %) key) terms))))
  43.397 +  (count [this] (count (.terms this)))
  43.398 +  (empty [this] (DifferentialSeq. []))
  43.399 +  (entryAt [this key]
  43.400 +	   ((juxt #(.partials %) #(.coefficient %))
  43.401 +	    (find-first #(= (.partials %) key) terms)))
  43.402 +  (seq [this] (seq (.terms this))))
  43.403 +
  43.404 +(def differential? #(= (type %) DifferentialSeq))
  43.405 +
  43.406 +(defn zeroth-order?
  43.407 +  "Returns true if the differential sequence has at most a constant term."
  43.408 +  [dseq]
  43.409 +  (and
  43.410 +   (differential? dseq)
  43.411 +   (every?
  43.412 +    #(= #{} %)
  43.413 +    (keys (.terms dseq)))))
  43.414 +
  43.415 +(defmethod fmap DifferentialSeq
  43.416 +  [f dseq]
  43.417 +  (DifferentialSeq.
  43.418 +   (fmap f (.terms dseq))))
  43.419 +
  43.420 +
  43.421 +
  43.422 +
  43.423 +;; BUILDING DIFFERENTIAL OBJECTS
  43.424 +
  43.425 +(defn differential-seq
  43.426 +    "Define a differential sequence by specifying an alternating
  43.427 +sequence of coefficients and lists of partials."
  43.428 +  ([coefficient partials]
  43.429 +     (DifferentialSeq. {(set partials) coefficient}))
  43.430 +  ([coefficient partials & cps]
  43.431 +     (if (odd? (count cps))
  43.432 +       (throw (Exception. "differential-seq requires an even number of terms."))
  43.433 +       (DifferentialSeq.
  43.434 +	(reduce
  43.435 +	 #(assoc %1 (set (second %2)) (first %2))
  43.436 +	 {(set partials) coefficient}
  43.437 +	 (partition 2 cps))))))
  43.438 +  
  43.439 +
  43.440 +
  43.441 +(defn big-part
  43.442 +  "Returns the part of the differential sequence that is finite,
  43.443 +  i.e. not infinitely small. If the sequence is zeroth-order, returns
  43.444 +  the coefficient of the zeroth-order term instead. "
  43.445 +  [dseq]
  43.446 +  (if (zeroth-order? dseq) (get (.terms dseq) #{})
  43.447 +      (let [m (.terms dseq)
  43.448 +	    keys (sort-by count (keys m))
  43.449 +	    smallest-var (last (last keys))]
  43.450 +	(DifferentialSeq.
  43.451 +	 (reduce
  43.452 +	  #(assoc %1 (first %2) (second %2))
  43.453 +	  {}
  43.454 +	  (remove #((first %) smallest-var) m))))))
  43.455 +
  43.456 +
  43.457 +(defn small-part
  43.458 +  "Returns the part of the differential sequence that infinitely
  43.459 +  small. If the sequence is zeroth-order, returns zero."
  43.460 +  [dseq]
  43.461 +  (if (zeroth-order? dseq) 0
  43.462 +      (let [m (.terms dseq)
  43.463 +	    keys (sort-by count (keys m))
  43.464 +	    smallest-var (last (last keys))]
  43.465 +	(DifferentialSeq.
  43.466 +	 (reduce
  43.467 +	  #(assoc %1 (first %2) (second %2)) {}
  43.468 +	  (filter #((first %) smallest-var) m))))))
  43.469 +
  43.470 +
  43.471 +
  43.472 +(defn cartesian-product [set1 set2]
  43.473 +  (reduce concat
  43.474 +	  (for [x set1]
  43.475 +	    (for [y set2]
  43.476 +	      [x y]))))
  43.477 +
  43.478 +(defn nth-subset [n]
  43.479 +  (if (zero? n) []
  43.480 +      (let [lg2 #(/ (log %) (log 2))
  43.481 +	    k (int(java.lang.Math/floor (lg2 n)))
  43.482 +	    ]
  43.483 +	(cons k
  43.484 +	 (nth-subset  (- n (pow 2 k)))))))
  43.485 +    
  43.486 +(def all-partials
  43.487 +     (lazy-seq (map nth-subset (range))))
  43.488 +
  43.489 +
  43.490 +(defn differential-multiply
  43.491 +  "Multiply two differential sequences. The square of any differential
  43.492 +  variable is zero since differential variables are infinitesimally
  43.493 +  small."
  43.494 +  [dseq1 dseq2]
  43.495 +  (DifferentialSeq.
  43.496 +   (reduce
  43.497 +    (fn [m [[vars1 coeff1] [vars2 coeff2]]]
  43.498 +      (if (not (empty? (clojure.set/intersection vars1 vars2)))
  43.499 +	m
  43.500 +	(assoc m (clojure.set/union vars1 vars2) (* coeff1 coeff2))))
  43.501 +    {}
  43.502 +    (cartesian-product (.terms dseq1) (.terms dseq2)))))
  43.503 +
  43.504 +
  43.505 +
  43.506 +(defmethod * [DifferentialSeq DifferentialSeq]
  43.507 +  [dseq1 dseq2]
  43.508 +   (differential-multiply dseq1 dseq2))
  43.509 +
  43.510 +(defmethod + [DifferentialSeq DifferentialSeq]
  43.511 +  [dseq1 dseq2]
  43.512 +  (DifferentialSeq.
  43.513 +   (merge-with + (.terms dseq1) (.terms dseq2))))
  43.514 +
  43.515 +(defmethod * [java.lang.Number DifferentialSeq]
  43.516 +  [x dseq]
  43.517 +  (fmap (partial * x) dseq))
  43.518 +
  43.519 +(defmethod * [DifferentialSeq java.lang.Number]
  43.520 +  [dseq x]
  43.521 +  (fmap (partial * x) dseq))
  43.522 +
  43.523 +(defmethod + [java.lang.Number DifferentialSeq]
  43.524 +  [x dseq]
  43.525 +  (+ (differential-seq x []) dseq))
  43.526 +(defmethod + [DifferentialSeq java.lang.Number]
  43.527 +  [dseq x]
  43.528 +  (+ dseq (differential-seq x [])))
  43.529 +
  43.530 +(defmethod - DifferentialSeq
  43.531 +  [x]
  43.532 +  (fmap - x))
  43.533 +
  43.534 +
  43.535 +;; DERIVATIVES
  43.536 +
  43.537 +	      
  43.538 +
  43.539 +(defn linear-approximator
  43.540 +  "Returns an operator that linearly approximates the given function."
  43.541 +  ([f df|dx]
  43.542 +      (fn [x]
  43.543 +	(let [big-part (big-part x)
  43.544 +	      small-part (small-part x)]
  43.545 +	  ;; f(x+dx) ~= f(x) + f'(x)dx
  43.546 +	  (+ (f big-part)
  43.547 +	     (* (df|dx big-part) small-part)
  43.548 +	  ))))
  43.549 +     
  43.550 +  ([f df|dx df|dy]
  43.551 +     (fn [x y]
  43.552 +       (let [X (big-part x)
  43.553 +	     Y (big-part y)
  43.554 +	     DX (small-part x)
  43.555 +	     DY (small-part y)]
  43.556 +	 (+ (f X Y)
  43.557 +	    (* DX (f df|dx X Y))
  43.558 +	    (* DY (f df|dy X Y)))))))
  43.559 +
  43.560 +
  43.561 +
  43.562 +
  43.563 +
  43.564 +(defn D[f]
  43.565 +  (fn[x] (f (+ x (differential-seq  1 [0] 1 [1] 1 [2])))))
  43.566 +  
  43.567 +(defn d[partials f]
  43.568 +  (fn [x]
  43.569 +    (get 
  43.570 +     (.terms ((D f)x))
  43.571 +     (set partials)
  43.572 +     0
  43.573 +    )))
  43.574 +
  43.575 +(defmethod exp DifferentialSeq [x]
  43.576 +	   ((linear-approximator exp exp) x))
  43.577 +
  43.578 +(defmethod sin DifferentialSeq
  43.579 +  [x]
  43.580 +  ((linear-approximator sin cos) x))
  43.581 +
  43.582 +(defmethod cos DifferentialSeq
  43.583 +  [x]
  43.584 +  ((linear-approximator cos #(- (sin %))) x))
  43.585 +
  43.586 +(defmethod log DifferentialSeq
  43.587 +  [x]
  43.588 +  ((linear-approximator log (fn [x] (/ x)) ) x))
  43.589 +
  43.590 +(defmethod / [DifferentialSeq DifferentialSeq]
  43.591 +  [x y]
  43.592 +  ((linear-approximator /
  43.593 +			(fn [x y] (/ 1 y))
  43.594 +			(fn [x y] (- (/ x (* y y)))))
  43.595 +   x y))
  43.596 +
  43.597 +#+end_src
  43.598 +
  43.599 +
  43.600 +
  43.601 +* Derivatives Revisited
  43.602 +#+begin_src clojure
  43.603 +(in-ns 'sicm.utils)
  43.604 +(use 'clojure.contrib.seq
  43.605 +     'clojure.contrib.generic.arithmetic
  43.606 +     'clojure.contrib.generic.collection
  43.607 +     'clojure.contrib.generic.math-functions)
  43.608 +
  43.609 +(defn replace-in
  43.610 +  "Replaces the nth item in coll with the given item. If n is larger
  43.611 +  than the size of coll, adds n to the end of the collection."
  43.612 +  [coll n item]
  43.613 +  (concat
  43.614 +   (take n coll)
  43.615 +   [item]
  43.616 +   (drop (inc n) coll)))
  43.617 +
  43.618 +(defn euclidean-structure [f partials]
  43.619 +  (fn sd[g v]
  43.620 +    (cond
  43.621 +     (tuple? v)
  43.622 +     (opposite-spin
  43.623 +      v
  43.624 +      (map
  43.625 +       (fn [n]
  43.626 +	 (sd (fn [xn]
  43.627 +	       (g
  43.628 +		(same-spin v
  43.629 +			   (replace-in v n xn))))
  43.630 +	     (nth v n)))
  43.631 +       (range (count v)))))))
  43.632 +   
  43.633 +      
  43.634 +  
  43.635 +
  43.636 +#+end_src
  43.637 +
  43.638 +
  43.639 +* Symbolic Quantities
  43.640 +
  43.641 +#+srcname: symbolic
  43.642 +#+begin_src clojure
  43.643 +(in-ns 'sicm.utils)
  43.644 +(use 'clojure.contrib.generic.arithmetic
  43.645 +     'clojure.contrib.generic.math-functions)
  43.646 +
  43.647 +(deftype Symbolic
  43.648 +  [type
  43.649 +   expression])
  43.650 +
  43.651 +(defn print-expression [s]
  43.652 +  (print (.expression  s)))
  43.653 +
  43.654 +(defn symbolic-number
  43.655 +  [symbol]
  43.656 +  (Symbolic. java.lang.Number symbol))
  43.657 +    
  43.658 +(defn simplify-expression [s]
  43.659 +  (let [e (.expression s)]
  43.660 +    (cond
  43.661 +     (not(list? e)) e
  43.662 +     (= (first e) '+) 
  43.663 +)
  43.664 +
  43.665 +
  43.666 +
  43.667 +(defmethod + [Symbolic Symbolic]
  43.668 +  [x y]
  43.669 +  (Symbolic. (.type x) (list '+ (.expression x) (.expression y))))
  43.670 +
  43.671 +(defmethod + [Symbolic java.lang.Number]
  43.672 +  [s x]
  43.673 +  (if (zero? x)
  43.674 +    s
  43.675 +    (Symbolic. (.type s) (list '+ (.expression s) x))))
  43.676 +
  43.677 +(defmethod sin Symbolic
  43.678 +  [s]
  43.679 +  (Symbolic. (.type s) (list 'sin (.expression s))))
  43.680 +
  43.681 +#+end_src
  43.682 +
  43.683 +* COMMENT To-be-tangled Source
  43.684 +#+begin_src clojure :tangle utils.clj
  43.685 +(ns sicm.utils)
  43.686 +
  43.687 +<<tuples>>
  43.688 +<<matrices>>
  43.689 +<<arith-tuple>>
  43.690 +
  43.691 +<<differential>>
  43.692 +#+end_src
  43.693 +