Mercurial > dylan
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 »"/> 1.96 + </form> 1.97 + --> 1.98 + </div> 1.99 + 1.100 + <h1>aurellem <em>☉</em></h1> 1.101 + <ul class="nav"> 1.102 + <li><a href="/">read the blog »</a></li> 1.103 + <!-- li><a href="#">learn about us »</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 “sequences with spin” </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 “sequences with spin” </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 + [& 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 + [& 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 + [& 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 & 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 & 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;">∂</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 & 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>