diff sicm/utils.html @ 2:b4de894a1e2e

initial import
author Robert McIntyre <rlm@mit.edu>
date Fri, 28 Oct 2011 00:03:05 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/sicm/utils.html	Fri Oct 28 00:03:05 2011 -0700
     1.3 @@ -0,0 +1,702 @@
     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>Building a Classical Mechanics Library in Clojure</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-08-11 04:10:36 EDT"/>
    1.14 +<meta name="author" content="Dylan Holmes"/>
    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 +<link rel="stylesheet" type="text/css" href="../css/aurellem.css" />
    1.61 +<script type="text/javascript">
    1.62 +<!--/*--><![CDATA[/*><!--*/
    1.63 + function CodeHighlightOn(elem, id)
    1.64 + {
    1.65 +   var target = document.getElementById(id);
    1.66 +   if(null != target) {
    1.67 +     elem.cacheClassElem = elem.className;
    1.68 +     elem.cacheClassTarget = target.className;
    1.69 +     target.className = "code-highlighted";
    1.70 +     elem.className   = "code-highlighted";
    1.71 +   }
    1.72 + }
    1.73 + function CodeHighlightOff(elem, id)
    1.74 + {
    1.75 +   var target = document.getElementById(id);
    1.76 +   if(elem.cacheClassElem)
    1.77 +     elem.className = elem.cacheClassElem;
    1.78 +   if(elem.cacheClassTarget)
    1.79 +     target.className = elem.cacheClassTarget;
    1.80 + }
    1.81 +/*]]>*///-->
    1.82 +</script>
    1.83 +
    1.84 +</head>
    1.85 +<body>
    1.86 +
    1.87 +<div id="content">
    1.88 +
    1.89 +
    1.90 +
    1.91 +<div class="header">
    1.92 +  <div class="float-right">	
    1.93 +    <!-- 
    1.94 +    <form>
    1.95 +      <input type="text"/><input type="submit" value="search the blog &raquo;"/> 
    1.96 +    </form>
    1.97 +    -->
    1.98 +  </div>
    1.99 +
   1.100 +  <h1>aurellem <em>&#x2609;</em></h1>
   1.101 +  <ul class="nav">
   1.102 +    <li><a href="/">read the blog &raquo;</a></li>
   1.103 +    <!-- li><a href="#">learn about us &raquo;</a></li-->
   1.104 +  </ul>
   1.105 +</div>
   1.106 +
   1.107 +<h1 class="title">Building a Classical Mechanics Library in Clojure</h1>
   1.108 +
   1.109 +
   1.110 +
   1.111 +
   1.112 +
   1.113 +
   1.114 +
   1.115 +<div id="table-of-contents">
   1.116 +<h2>Table of Contents</h2>
   1.117 +<div id="text-table-of-contents">
   1.118 +<ul>
   1.119 +<li><a href="#sec-1">1 Useful data types </a>
   1.120 +<ul>
   1.121 +<li><a href="#sec-1-1">1.1 Complex numbers </a></li>
   1.122 +<li><a href="#sec-1-2">1.2 Power series </a></li>
   1.123 +<li><a href="#sec-1-3">1.3 Tuples and tensors </a>
   1.124 +<ul>
   1.125 +<li><a href="#sec-1-3-1">1.3.1 Tuples are &ldquo;sequences with spin&rdquo; </a></li>
   1.126 +<li><a href="#sec-1-3-2">1.3.2 Matrices </a></li>
   1.127 +</ul>
   1.128 +</li>
   1.129 +<li><a href="#sec-1-4">1.4 Generic Operations </a></li>
   1.130 +</ul>
   1.131 +</li>
   1.132 +<li><a href="#sec-2">2 Operators and Differentiation </a>
   1.133 +<ul>
   1.134 +<li><a href="#sec-2-1">2.1 Operators </a></li>
   1.135 +<li><a href="#sec-2-2">2.2 Differential Terms and Sequences </a></li>
   1.136 +</ul>
   1.137 +</li>
   1.138 +</ul>
   1.139 +</div>
   1.140 +</div>
   1.141 +
   1.142 +<div id="outline-container-1" class="outline-2">
   1.143 +<h2 id="sec-1"><span class="section-number-2">1</span> Useful data types </h2>
   1.144 +<div class="outline-text-2" id="text-1">
   1.145 +
   1.146 +
   1.147 +
   1.148 +</div>
   1.149 +
   1.150 +<div id="outline-container-1-1" class="outline-3">
   1.151 +<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Complex numbers </h3>
   1.152 +<div class="outline-text-3" id="text-1-1">
   1.153 +
   1.154 +
   1.155 +</div>
   1.156 +
   1.157 +</div>
   1.158 +
   1.159 +<div id="outline-container-1-2" class="outline-3">
   1.160 +<h3 id="sec-1-2"><span class="section-number-3">1.2</span> Power series </h3>
   1.161 +<div class="outline-text-3" id="text-1-2">
   1.162 +
   1.163 +
   1.164 +</div>
   1.165 +
   1.166 +</div>
   1.167 +
   1.168 +<div id="outline-container-1-3" class="outline-3">
   1.169 +<h3 id="sec-1-3"><span class="section-number-3">1.3</span> Tuples and tensors </h3>
   1.170 +<div class="outline-text-3" id="text-1-3">
   1.171 +
   1.172 +
   1.173 +
   1.174 +</div>
   1.175 +
   1.176 +<div id="outline-container-1-3-1" class="outline-4">
   1.177 +<h4 id="sec-1-3-1"><span class="section-number-4">1.3.1</span> Tuples are &ldquo;sequences with spin&rdquo; </h4>
   1.178 +<div class="outline-text-4" id="text-1-3-1">
   1.179 +
   1.180 +
   1.181 +
   1.182 +
   1.183 +
   1.184 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
   1.185 +
   1.186 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">Let some objects have spin</span>
   1.187 +
   1.188 +(<span style="color: #f0dfaf; font-weight: bold;">defprotocol</span> <span style="color: #f0dfaf;">Spinning</span>
   1.189 +  (up? [this])
   1.190 +  (down? [this]))
   1.191 +
   1.192 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">spin</span>
   1.193 +  <span style="color: #8fb28f;">"Returns the spin of the Spinning s, either :up or :down"</span>
   1.194 +  [<span style="color: #dfdfbf; font-weight: bold;">#^Spinning</span> s]
   1.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>))
   1.196 +
   1.197 +
   1.198 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">DEFINITION: A tuple is a sequence with spin</span>
   1.199 +
   1.200 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">Tuple</span>
   1.201 +  [spin coll]
   1.202 +
   1.203 +  clojure.lang.Seqable
   1.204 +  (<span style="color: #8cd0d3;">seq</span> [this] (<span style="color: #8cd0d3;">seq</span> (.coll this)))
   1.205 +
   1.206 +  clojure.lang.Counted
   1.207 +  (<span style="color: #8cd0d3;">count</span> [this] (<span style="color: #8cd0d3;">count</span> (.coll this)))
   1.208 +
   1.209 +  Spinning
   1.210 +  (up? [this] (<span style="color: #8cd0d3;">=</span> <span style="color: #8cd0d3;">::up</span> (.spin this)))
   1.211 +  (down? [this] (<span style="color: #8cd0d3;">=</span> <span style="color: #8cd0d3;">::down</span> (.spin this))))
   1.212 +
   1.213 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">print-method</span> Tuple
   1.214 +  [o w]
   1.215 +  (<span style="color: #8cd0d3;">print-simple</span>
   1.216 +   (<span style="color: #f0dfaf; font-weight: bold;">if</span> (up? o)
   1.217 +     (<span style="color: #8cd0d3;">str</span> <span style="color: #cc9393;">"u"</span> (.coll o))
   1.218 +     (<span style="color: #8cd0d3;">str</span> <span style="color: #cc9393;">"d"</span> (<span style="color: #8cd0d3;">vec</span>(.coll o))))
   1.219 +   w))
   1.220 +
   1.221 +
   1.222 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">CONSTRUCTORS</span>
   1.223 +
   1.224 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">up</span>
   1.225 +  <span style="color: #8fb28f;">"Create a new up-tuple containing the contents of coll."</span>
   1.226 +  [coll]
   1.227 +  (Tuple. <span style="color: #8cd0d3;">::up</span> coll))       
   1.228 +
   1.229 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">down</span>
   1.230 +  <span style="color: #8fb28f;">"Create a new down-tuple containing the contents of coll."</span>
   1.231 +  [coll]
   1.232 +  (Tuple. <span style="color: #8cd0d3;">::down</span> coll))
   1.233 +</pre>
   1.234 +
   1.235 +
   1.236 +
   1.237 +
   1.238 +
   1.239 +
   1.240 +</div>
   1.241 +
   1.242 +</div>
   1.243 +
   1.244 +<div id="outline-container-1-3-2" class="outline-4">
   1.245 +<h4 id="sec-1-3-2"><span class="section-number-4">1.3.2</span> Matrices </h4>
   1.246 +<div class="outline-text-4" id="text-1-3-2">
   1.247 +
   1.248 +
   1.249 +
   1.250 +
   1.251 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
   1.252 +(<span style="color: #8cd0d3;">require</span> 'incanter.core) <span style="color: #708070;">;; </span><span style="color: #7f9f7f;">use incanter's fast matrices</span>
   1.253 +
   1.254 +
   1.255 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">all-equal?</span> [coll]
   1.256 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">empty?</span> (<span style="color: #8cd0d3;">rest</span> coll)) true
   1.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))
   1.258 +           (<span style="color: #f0dfaf; font-weight: bold;">recur</span> (<span style="color: #8cd0d3;">rest</span> coll)))))
   1.259 +
   1.260 +
   1.261 +(<span style="color: #f0dfaf; font-weight: bold;">defprotocol</span> <span style="color: #f0dfaf;">Matrix</span>
   1.262 +  (rows [matrix])
   1.263 +  (cols [matrix])
   1.264 +  (diagonal [matrix])
   1.265 +  (trace [matrix])
   1.266 +  (determinant [matrix])
   1.267 +  (transpose [matrix])
   1.268 +  (conjugate [matrix])
   1.269 +)
   1.270 +
   1.271 +(<span style="color: #8cd0d3;">extend-protocol</span> Matrix incanter.Matrix
   1.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))))
   1.273 +  (cols [rs] (<span style="color: #8cd0d3;">map</span> up (<span style="color: #8cd0d3;">apply</span> map vector rs)))
   1.274 +  (diagonal [matrix] (incanter.core/diag matrix) )
   1.275 +  (determinant [matrix] (incanter.core/det matrix))
   1.276 +  (trace [matrix] (incanter.core/trace matrix))
   1.277 +  (transpose [matrix] (incanter.core/trans matrix)))
   1.278 +
   1.279 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">count-rows</span> [matrix]
   1.280 +  ((<span style="color: #8cd0d3;">comp</span> count rows) matrix))
   1.281 +
   1.282 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">count-cols</span> [matrix]
   1.283 +  ((<span style="color: #8cd0d3;">comp</span> count cols) matrix))
   1.284 +
   1.285 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">square?</span> [matrix]
   1.286 +  (<span style="color: #8cd0d3;">=</span> (count-rows matrix) (count-cols matrix)))
   1.287 +
   1.288 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">identity-matrix</span>
   1.289 +  <span style="color: #8fb28f;">"Define a square matrix of size n-by-n with 1s along the diagonal and</span>
   1.290 +<span style="color: #8fb28f;">  0s everywhere else."</span>
   1.291 +  [n]
   1.292 +  (incanter.core/identity-matrix n))
   1.293 +
   1.294 +
   1.295 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">matrix-by-rows</span>
   1.296 +  <span style="color: #8fb28f;">"Define a matrix by giving its rows."</span>
   1.297 +  [&amp; rows]
   1.298 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span>
   1.299 +   (<span style="color: #8cd0d3;">not</span> (all-equal? (<span style="color: #8cd0d3;">map</span> count rows)))
   1.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>))
   1.301 +   (incanter.core/matrix (<span style="color: #8cd0d3;">vec</span> rows))))
   1.302 +
   1.303 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">matrix-by-cols</span>
   1.304 +  <span style="color: #8fb28f;">"Define a matrix by giving its columns"</span>
   1.305 +  [&amp; cols]
   1.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)))
   1.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>))
   1.308 +   (incanter.core/matrix (<span style="color: #8cd0d3;">vec</span> (<span style="color: #8cd0d3;">apply</span> map vector cols)))))
   1.309 +
   1.310 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">identity-matrix</span>
   1.311 +  <span style="color: #8fb28f;">"Define a square matrix of size n-by-n with 1s along the diagonal and</span>
   1.312 +<span style="color: #8fb28f;">  0s everywhere else."</span>
   1.313 +  [n]
   1.314 +  (incanter.core/identity-matrix n))
   1.315 +
   1.316 +</pre>
   1.317 +
   1.318 +
   1.319 +
   1.320 +
   1.321 +</div>
   1.322 +</div>
   1.323 +
   1.324 +</div>
   1.325 +
   1.326 +<div id="outline-container-1-4" class="outline-3">
   1.327 +<h3 id="sec-1-4"><span class="section-number-3">1.4</span> Generic Operations </h3>
   1.328 +<div class="outline-text-3" id="text-1-4">
   1.329 +
   1.330 +
   1.331 +
   1.332 +
   1.333 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
   1.334 +(<span style="color: #8cd0d3;">use</span> 'clojure.contrib.generic.arithmetic
   1.335 +     'clojure.contrib.generic.collection
   1.336 +     'clojure.contrib.generic.functor
   1.337 +     'clojure.contrib.generic.math-functions)
   1.338 +
   1.339 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">numbers?</span>
   1.340 +  <span style="color: #8fb28f;">"Returns true if all arguments are numbers, else false."</span>
   1.341 +  [&amp; xs]
   1.342 +  (<span style="color: #8cd0d3;">every?</span> number? xs))
   1.343 +
   1.344 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">tuple-surgery</span>
   1.345 +  <span style="color: #8fb28f;">"Applies the function f to the items of tuple and the additional</span>
   1.346 +<span style="color: #8fb28f;">  arguments, if any. Returns a Tuple of the same type as tuple."</span>
   1.347 +  [tuple f &amp; xs]
   1.348 +  ((<span style="color: #f0dfaf; font-weight: bold;">if</span> (up? tuple) up down)
   1.349 +   (<span style="color: #8cd0d3;">apply</span> f (<span style="color: #8cd0d3;">seq</span> tuple) xs)))
   1.350 +
   1.351 +
   1.352 +
   1.353 +<span style="color: #708070;">;;; </span><span style="color: #7f9f7f;">CONTRACTION collapses two compatible tuples into a number.</span>
   1.354 +
   1.355 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">contractible?</span>
   1.356 +  <span style="color: #8fb28f;">"Returns true if the tuples a and b are compatible for contraction,</span>
   1.357 +<span style="color: #8fb28f;">  else false. Tuples are compatible if they have the same number of</span>
   1.358 +<span style="color: #8fb28f;">  components, they have opposite spins, and their elements are</span>
   1.359 +<span style="color: #8fb28f;">  pairwise-compatible."</span>
   1.360 +  [a b]
   1.361 +  (<span style="color: #f0dfaf; font-weight: bold;">and</span>
   1.362 +   (<span style="color: #8cd0d3;">isa?</span> (<span style="color: #8cd0d3;">type</span> a) Tuple)
   1.363 +   (<span style="color: #8cd0d3;">isa?</span> (<span style="color: #8cd0d3;">type</span> b) Tuple)
   1.364 +   (<span style="color: #8cd0d3;">=</span> (<span style="color: #8cd0d3;">count</span> a) (<span style="color: #8cd0d3;">count</span> b))
   1.365 +   (<span style="color: #8cd0d3;">not=</span> (spin a) (spin b))
   1.366 +   
   1.367 +   (<span style="color: #8cd0d3;">not-any?</span> false?
   1.368 +             (<span style="color: #8cd0d3;">map</span> #(<span style="color: #f0dfaf; font-weight: bold;">or</span>
   1.369 +                    (numbers? %1 %2)
   1.370 +                    (contractible? %1 %2))
   1.371 +                  a b))))
   1.372 +
   1.373 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">contract</span>
   1.374 +  <span style="color: #8fb28f;">"Contracts two tuples, returning the sum of the</span>
   1.375 +<span style="color: #8fb28f;">  products of the corresponding items. Contraction is recursive on</span>
   1.376 +<span style="color: #8fb28f;">  nested tuples."</span>
   1.377 +  [a b]
   1.378 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">not</span> (contractible? a b))
   1.379 +    (<span style="color: #f0dfaf; font-weight: bold;">throw</span>
   1.380 +     (Exception. <span style="color: #cc9393;">"Not compatible for contraction."</span>))
   1.381 +    (<span style="color: #8cd0d3;">reduce</span> +
   1.382 +            (<span style="color: #8cd0d3;">map</span>
   1.383 +             (<span style="color: #8cd0d3;">fn</span> [x y]
   1.384 +               (<span style="color: #f0dfaf; font-weight: bold;">if</span> (numbers? x y)
   1.385 +                 (<span style="color: #8cd0d3;">*</span> x y)
   1.386 +                 (contract x y)))
   1.387 +             a b))))
   1.388 +
   1.389 +
   1.390 +
   1.391 +
   1.392 +
   1.393 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">conj</span> Tuple
   1.394 +  [tuple &amp; xs]
   1.395 +  (tuple-surgery tuple #(<span style="color: #8cd0d3;">apply</span> conj % xs)))
   1.396 +
   1.397 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">fmap</span> Tuple
   1.398 +  [f tuple]
   1.399 +  (tuple-surgery tuple (<span style="color: #8cd0d3;">partial</span> map f)))
   1.400 +
   1.401 +
   1.402 +
   1.403 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">TODO: define Scalar, and add it to the hierarchy above Number and Complex</span>
   1.404 +
   1.405 +                                        
   1.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>
   1.407 +  [a b]
   1.408 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (contractible? a b)
   1.409 +    (contract a b)
   1.410 +    (<span style="color: #8cd0d3;">map</span> (<span style="color: #8cd0d3;">partial</span> * a) b)))
   1.411 +
   1.412 +
   1.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>
   1.414 +  [a x] (fmap (<span style="color: #8cd0d3;">partial</span> * a) x))
   1.415 +
   1.416 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [Tuple java.lang.Number]
   1.417 +  [x a] (<span style="color: #8cd0d3;">*</span> a x))
   1.418 +
   1.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>
   1.420 +  [x M] (incanter.core/mult x M))
   1.421 +
   1.422 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [incanter.Matrix java.lang.Number]
   1.423 +  [M x] (<span style="color: #8cd0d3;">*</span> x M))
   1.424 +
   1.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>
   1.426 +  [M1 M2]
   1.427 +  (incanter.core/mmult M1 M2))
   1.428 +
   1.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>
   1.430 +  [M v]
   1.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)) 
   1.432 +    (<span style="color: #8cd0d3;">*</span> M (matrix-by-cols v))
   1.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>))
   1.434 +    ))
   1.435 +
   1.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>
   1.437 +  [v M]
   1.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))
   1.439 +    (<span style="color: #8cd0d3;">*</span> (matrix-by-rows v) M)
   1.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>))
   1.441 +    ))
   1.442 +
   1.443 +
   1.444 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">exp</span> incanter.Matrix
   1.445 +  [M]
   1.446 +  (incanter.core/exp M))
   1.447 +
   1.448 +</pre>
   1.449 +
   1.450 +
   1.451 +
   1.452 +
   1.453 +</div>
   1.454 +</div>
   1.455 +
   1.456 +</div>
   1.457 +
   1.458 +<div id="outline-container-2" class="outline-2">
   1.459 +<h2 id="sec-2"><span class="section-number-2">2</span> Operators and Differentiation </h2>
   1.460 +<div class="outline-text-2" id="text-2">
   1.461 +
   1.462 +
   1.463 +
   1.464 +
   1.465 +</div>
   1.466 +
   1.467 +<div id="outline-container-2-1" class="outline-3">
   1.468 +<h3 id="sec-2-1"><span class="section-number-3">2.1</span> Operators </h3>
   1.469 +<div class="outline-text-3" id="text-2-1">
   1.470 +
   1.471 +
   1.472 +</div>
   1.473 +
   1.474 +</div>
   1.475 +
   1.476 +<div id="outline-container-2-2" class="outline-3">
   1.477 +<h3 id="sec-2-2"><span class="section-number-3">2.2</span> Differential Terms and Sequences </h3>
   1.478 +<div class="outline-text-3" id="text-2-2">
   1.479 +
   1.480 +
   1.481 +
   1.482 +
   1.483 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'sicm.utils)
   1.484 +(<span style="color: #8cd0d3;">use</span> 'clojure.contrib.seq
   1.485 +     'clojure.contrib.generic.arithmetic
   1.486 +     'clojure.contrib.generic.collection
   1.487 +     'clojure.contrib.generic.math-functions)
   1.488 +
   1.489 +<span style="color: #708070;">;;</span><span style="color: #7f9f7f;">&#8706;</span>
   1.490 +
   1.491 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">DEFINITION : Differential Term</span>
   1.492 +
   1.493 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">A quantity with infinitesimal components, e.g. x, dxdy, 4dydz. The</span>
   1.494 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">coefficient of the quantity is returned by the 'coefficient' method,</span>
   1.495 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">while the sequence of differential parameters is returned by the</span>
   1.496 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">method 'partials'.</span>
   1.497 +
   1.498 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">Instead of using (potentially ambiguous) letters to denote</span>
   1.499 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">differential parameters (dx,dy,dz), we use integers. So, dxdz becomes [0 2].</span>
   1.500 +
   1.501 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">The coefficient can be any arithmetic object; the</span>
   1.502 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">partials must be a nonrepeating sorted sequence of nonnegative</span>
   1.503 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">integers.</span>
   1.504 +
   1.505 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">DifferentialTerm</span> [coefficient partials])
   1.506 +
   1.507 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-term</span>
   1.508 +  <span style="color: #8fb28f;">"Make a differential term given pairs of coefficients and partials."</span>
   1.509 +  [coefficient partials]
   1.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)) 
   1.511 +    (DifferentialTerm. coefficient (<span style="color: #8cd0d3;">set</span> partials))
   1.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>))))
   1.513 +
   1.514 +
   1.515 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">DEFINITION : Differential Sequence</span>
   1.516 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">A differential sequence is a sequence of differential terms, all with different partials.</span>
   1.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>
   1.518 +
   1.519 +(<span style="color: #f0dfaf; font-weight: bold;">deftype</span> <span style="color: #f0dfaf;">DifferentialSeq</span>
   1.520 +  [terms]
   1.521 +  <span style="color: #708070;">;;</span><span style="color: #7f9f7f;">clojure.lang.IPersistentMap</span>
   1.522 +  clojure.lang.Associative
   1.523 +  (<span style="color: #8cd0d3;">assoc</span> [this key val]
   1.524 +    (DifferentialSeq.
   1.525 +     (<span style="color: #8cd0d3;">cons</span> (differential-term val key) terms)))
   1.526 +  (<span style="color: #8cd0d3;">cons</span> [this x]
   1.527 +        (DifferentialSeq. (<span style="color: #8cd0d3;">cons</span> x terms)))
   1.528 +  (containsKey [this key]
   1.529 +               (<span style="color: #8cd0d3;">not</span>(<span style="color: #8cd0d3;">nil?</span> (find-first #(<span style="color: #8cd0d3;">=</span> (.partials %) key) terms))))
   1.530 +  (<span style="color: #8cd0d3;">count</span> [this] (<span style="color: #8cd0d3;">count</span> (.terms this)))
   1.531 +  (<span style="color: #8cd0d3;">empty</span> [this] (DifferentialSeq. []))
   1.532 +  (entryAt [this key]
   1.533 +           ((<span style="color: #8cd0d3;">juxt</span> #(.partials %) #(.coefficient %))
   1.534 +            (find-first #(<span style="color: #8cd0d3;">=</span> (.partials %) key) terms)))
   1.535 +  (<span style="color: #8cd0d3;">seq</span> [this] (<span style="color: #8cd0d3;">seq</span> (.terms this))))
   1.536 +
   1.537 +
   1.538 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">fmap</span> DifferentialSeq
   1.539 +  [f dseq]
   1.540 +  (DifferentialSeq. (fmap f (.terms dseq))))
   1.541 +
   1.542 +
   1.543 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">BUILDING DIFFERENTIAL OBJECTS</span>
   1.544 +
   1.545 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-seq</span>
   1.546 +    <span style="color: #8fb28f;">"Define a differential sequence by specifying coefficient/partials</span>
   1.547 +<span style="color: #8fb28f;">pairs, which are used to create differential terms to populate the</span>
   1.548 +<span style="color: #8fb28f;">sequence."</span>
   1.549 +  ([coefficient partials]
   1.550 +     (DifferentialSeq. {(<span style="color: #8cd0d3;">set</span> partials) coefficient}))
   1.551 +  ([coefficient partials &amp; cps]
   1.552 +     (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">odd?</span> (<span style="color: #8cd0d3;">count</span> cps))
   1.553 +       (<span style="color: #f0dfaf; font-weight: bold;">throw</span> (Exception. <span style="color: #cc9393;">"differential-seq requires an even number of terms."</span>))
   1.554 +       (DifferentialSeq.
   1.555 +        (<span style="color: #8cd0d3;">reduce</span>
   1.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))
   1.557 +         {(<span style="color: #8cd0d3;">set</span> partials) coefficient}
   1.558 +         (<span style="color: #8cd0d3;">partition</span> 2 cps))))))
   1.559 +  
   1.560 +
   1.561 +
   1.562 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">big-part</span>
   1.563 +  <span style="color: #8fb28f;">"Returns the part of the differential sequence that is finite,</span>
   1.564 +<span style="color: #8fb28f;">  i.e. not infinitely small, as a differential sequence. If given a</span>
   1.565 +<span style="color: #8fb28f;">  non-differential object, returns that object."</span>
   1.566 +  [dseq]
   1.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
   1.568 +      (<span style="color: #f0dfaf; font-weight: bold;">let</span> [m (.terms dseq)
   1.569 +            keys (<span style="color: #8cd0d3;">sort-by</span> count (<span style="color: #8cd0d3;">keys</span> m))
   1.570 +            smallest-var (<span style="color: #8cd0d3;">last</span> (<span style="color: #8cd0d3;">last</span> keys))]
   1.571 +        (DifferentialSeq.
   1.572 +         (<span style="color: #8cd0d3;">reduce</span>
   1.573 +          #(<span style="color: #8cd0d3;">assoc</span> %1 (<span style="color: #8cd0d3;">first</span> %2) (<span style="color: #8cd0d3;">second</span> %2))
   1.574 +          {}
   1.575 +          (<span style="color: #8cd0d3;">remove</span> #((<span style="color: #8cd0d3;">first</span> %) smallest-var) m))))))
   1.576 +
   1.577 +
   1.578 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">small-part</span>
   1.579 +  <span style="color: #8fb28f;">"Returns the part of the differential sequence that infinitely</span>
   1.580 +<span style="color: #8fb28f;">  small, as a differential sequence. If given a non-differential</span>
   1.581 +<span style="color: #8fb28f;">  object, returns that object."</span>
   1.582 +  [dseq]
   1.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
   1.584 +      (<span style="color: #f0dfaf; font-weight: bold;">let</span> [m (.terms dseq)
   1.585 +            keys (<span style="color: #8cd0d3;">sort-by</span> count (<span style="color: #8cd0d3;">keys</span> m))
   1.586 +            smallest-var (<span style="color: #8cd0d3;">last</span> (<span style="color: #8cd0d3;">last</span> keys))]
   1.587 +        (DifferentialSeq.
   1.588 +         (<span style="color: #8cd0d3;">reduce</span>
   1.589 +          #(<span style="color: #8cd0d3;">assoc</span> %1 (<span style="color: #8cd0d3;">first</span> %2) (<span style="color: #8cd0d3;">second</span> %2)) {}
   1.590 +          (<span style="color: #8cd0d3;">filter</span> #((<span style="color: #8cd0d3;">first</span> %) smallest-var) m))))))
   1.591 +
   1.592 +
   1.593 +
   1.594 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">cartesian-product</span> [set1 set2]
   1.595 +  (<span style="color: #8cd0d3;">reduce</span> concat
   1.596 +          (<span style="color: #f0dfaf; font-weight: bold;">for</span> [x set1]
   1.597 +            (<span style="color: #f0dfaf; font-weight: bold;">for</span> [y set2]
   1.598 +              [x y]))))
   1.599 +
   1.600 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">differential-multiply</span>
   1.601 +  <span style="color: #8fb28f;">"Multiply two differential sequences. The square of any differential</span>
   1.602 +<span style="color: #8fb28f;">  variable is zero since differential variables are infinitesimally</span>
   1.603 +<span style="color: #8fb28f;">  small."</span>
   1.604 +  [dseq1 dseq2]
   1.605 +  (DifferentialSeq.
   1.606 +   (<span style="color: #8cd0d3;">reduce</span>
   1.607 +    (<span style="color: #8cd0d3;">fn</span> [m [[vars1 coeff1] [vars2 coeff2]]]
   1.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)))
   1.609 +        m
   1.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))))
   1.611 +    {}
   1.612 +    (cartesian-product (.terms dseq1) (.terms dseq2)))))
   1.613 +
   1.614 +
   1.615 +
   1.616 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [DifferentialSeq DifferentialSeq]
   1.617 +  [dseq1 dseq2]
   1.618 +   (differential-multiply dseq1 dseq2))
   1.619 +
   1.620 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">+</span> [DifferentialSeq DifferentialSeq]
   1.621 +  [dseq1 dseq2]
   1.622 +  (DifferentialSeq.
   1.623 +   (<span style="color: #8cd0d3;">merge-with</span> + (.terms dseq1) (.terms dseq2))))
   1.624 +
   1.625 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [java.lang.Number DifferentialSeq]
   1.626 +  [x dseq]
   1.627 +  (fmap (<span style="color: #8cd0d3;">partial</span> * x) dseq))
   1.628 +
   1.629 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">*</span> [DifferentialSeq java.lang.Number]
   1.630 +  [dseq x]
   1.631 +  (fmap (<span style="color: #8cd0d3;">partial</span> * x) dseq))
   1.632 +<span style="color: #708070;">;; </span><span style="color: #7f9f7f;">DERIVATIVES</span>
   1.633 +
   1.634 +
   1.635 +
   1.636 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">linear-approximator</span>
   1.637 +  <span style="color: #8fb28f;">"Returns an operator that linearly approximates the given function."</span>
   1.638 +  ([f df|dx]
   1.639 +     (<span style="color: #8cd0d3;">fn</span> [x]
   1.640 +       (<span style="color: #f0dfaf; font-weight: bold;">let</span> [big-part (big-part x)
   1.641 +             small-part (small-part x)]
   1.642 +         (<span style="color: #8cd0d3;">+</span> (fmap f big-part)
   1.643 +            (<span style="color: #8cd0d3;">*</span> (fmap df|dx big-part) small-part)))))
   1.644 +  ([f df|dx df|dy]
   1.645 +     (<span style="color: #8cd0d3;">fn</span> [x y]
   1.646 +       (<span style="color: #f0dfaf; font-weight: bold;">let</span> [X (big-part x)
   1.647 +             Y (big-part y)
   1.648 +             DX (small-part x)
   1.649 +             DY (small-part y)]
   1.650 +         (<span style="color: #8cd0d3;">+</span> (f X Y)
   1.651 +            (<span style="color: #8cd0d3;">+</span> (<span style="color: #8cd0d3;">*</span> DX (df|dx X Y))
   1.652 +               (<span style="color: #8cd0d3;">*</span> DY (df|dy X Y)))))))
   1.653 +  )
   1.654 +
   1.655 +
   1.656 +
   1.657 +
   1.658 +
   1.659 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">D</span>[f]
   1.660 +  (<span style="color: #8cd0d3;">fn</span>[x]
   1.661 +    (f (differential-seq x [] 1 [0]))))
   1.662 +
   1.663 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">d</span>[f partials]
   1.664 +  (<span style="color: #8cd0d3;">fn</span> [x]
   1.665 +    (<span style="color: #8cd0d3;">get</span> 
   1.666 +     (.terms ((D f)x))
   1.667 +     (<span style="color: #8cd0d3;">set</span> partials)
   1.668 +     0
   1.669 +    )))
   1.670 +
   1.671 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">exp</span> DifferentialSeq [x]
   1.672 +           ((linear-approximator exp exp) x))
   1.673 +
   1.674 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">sin</span> DifferentialSeq
   1.675 +  [x]
   1.676 +  ((linear-approximator sin cos) x))
   1.677 +
   1.678 +(<span style="color: #f0dfaf; font-weight: bold;">defmethod</span> <span style="color: #f0dfaf;">cos</span> DifferentialSeq
   1.679 +  [x]
   1.680 +  ((linear-approximator cos #(<span style="color: #8cd0d3;">-</span> (sin %))) x))
   1.681 +     
   1.682 +
   1.683 +
   1.684 +</pre>
   1.685 +
   1.686 +
   1.687 +
   1.688 +
   1.689 +
   1.690 +
   1.691 +
   1.692 +
   1.693 +
   1.694 +</div>
   1.695 +</div>
   1.696 +</div>
   1.697 +<div id="postamble">
   1.698 +<p class="date">Date: 2011-08-11 04:10:36 EDT</p>
   1.699 +<p class="author">Author: Dylan Holmes</p>
   1.700 +<p class="creator">Org version 7.6 with Emacs version 23</p>
   1.701 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
   1.702 +</div>
   1.703 +</div>
   1.704 +</body>
   1.705 +</html>