<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Conal Elliott &#187; type family</title>
	<atom:link href="http://conal.net/blog/tag/type-family/feed/" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog</link>
	<description>Inspirations &#38; experiments, mainly about denotational programming in Haskell</description>
	<lastBuildDate>Fri, 30 Jul 2010 02:56:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Simpler, more efficient, functional linear maps</title>
		<link>http://conal.net/blog/posts/simpler-more-efficient-functional-linear-maps/</link>
		<comments>http://conal.net/blog/posts/simpler-more-efficient-functional-linear-maps/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 01:26:05 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[linear map]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[trie]]></category>
		<category><![CDATA[type family]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=57</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Simpler, more efficient, functional linear maps

Tags: vector spaces, linear maps, math, type families, memoization, tries

URL: http://conal.net/blog/posts/simpler-more-efficient-functional-linear-maps/

-->

<!-- references -->

<!-- teaser -->

<p>A <a href="http://conal.net/blog/posts/functional-linear-maps/" title="Blog post: &quot;Functional linear maps&quot;">previous post</a> described a data type of functional linear maps.
As <a href="http://www.unsafeperformio.com/index.php" title="Andy Gill's home page">Andy Gill</a> <a href="http://blog.unsafeperformio.com/?p=23" title="Blog post: &quot;Performance problems with functional representation of derivatives&quot;">pointed out</a>, we had a heck of a time trying to get good performance.
This note describes a new representation that is <em>very simple</em> and much more efficient.
It&#8217;s terribly obvious in retrospect but took me a good while to stumble onto.</p>

<p>The Haskell module described here is part of the <a href="http://haskell.org/haskellwiki/vector-space" title="Library wiki page: &quot;vector-space&quot;">vector-space library</a> (version 0.5 or later) and requires ghc version 6.10 or better (for associated types).</p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2008-11-09: Changed remarks about versions.  The vector-space version 0.5 depends on ghc 6.10.</li>
<li>2008-10-21: Fixed the <a href="http://haskell.org/haskellwiki/vector-space" title="Library wiki page: &quot;vector-space&quot;">vector-space library</a> link in the teaser.</li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-57"></span></p>

<h3>Linear maps</h3>

<p>Semantically, a <em>linear map</em> is a function <code>f :: a -&gt; b</code> such that, for all scalar values <code>s</code> and &#8220;vectors&#8221; <code>u, v :: a</code>, the following properties hold:</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/301/301ab9db4cdf97efebdbfde71acc1b25-ffffff000000.png' alt='f (s \cdot u) = s \cdot f u' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/864/86429c558884d2a47481163eb3bcb653-ffffff000000.png' alt='f (u + v) = f u + f v' class='latex' /></div></p>

<p>By repeated application of these properties,</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/c1d/c1df825c8a572e687fac4dc1d73edadb-ffffff000000.png' alt='f (s_1 \cdot u_1 + \cdots + s_n \cdot u_n) = s_1 \cdot f u_1 + \cdots + s_n \cdot f u_n' class='latex' /></div></p>

<p>Taking the <em>u<sub>i</sub></em> as basis vectors, this form implies that a linear function is determined by its behavior on any <a href="http://en.wikipedia.org/wiki/Basis_(linear_algebra)" title="Wikipedia article">basis</a> of its domain type.</p>

<p>Therefore, a linear function can be represented simply as a function from a basis, using the representation described in <a href="http://conal.net/blog/posts/vector-space-bases-via-type-families/" title="Blog post: &quot;Vector space bases via type families&quot;">Vector space bases via type families</a>.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> u :-* v = Basis u -&gt; v</pre>
</div></p>

<p>The semantic function converts from <code>(u :-* v)</code> to <code>(u -&gt; v)</code>.
It decomposes a source vector into its coordinates, applies the basis function to basis representations, and linearly combines the results.</p>

<p><div>
<pre class="haskell">lapply :: <span style="color: green;">&#40;</span> VectorSpace u, VectorSpace v
          , Scalar u ~ Scalar v, HasBasis u <span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>u :-* v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>u -&gt; v<span style="color: green;">&#41;</span>
lapply lm = \ u -&gt; sumV <span style="color: green;">&#91;</span>s *^ lm b | <span style="color: green;">&#40;</span>b,s<span style="color: green;">&#41;</span> &lt;- decompose u<span style="color: green;">&#93;</span></pre>
</div></p>

<p>or</p>

<p><div>
<pre class="haskell">lapply lm = linearCombo . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> lm<span style="color: green;">&#41;</span> . decompose</pre>
</div></p>

<p>The reverse function is easier.
Convert a function <code>f</code>, presumed linear, to a linear map representation:</p>

<p><div>
<pre class="haskell">linear :: <span style="color: green;">&#40;</span>VectorSpace u, VectorSpace v, HasBasis u<span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>u -&gt; v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>u :-* v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>It suffices to apply <code>f</code> to basis values:</p>

<p><div>
<pre class="haskell">linear f = f . basisValue</pre>
</div></p>

<h3>Memoization</h3>

<p>The idea of the linear map representation is to reconstruct an entire (linear) function out of just a few samples.
In other words, we can make a very small sampling of function&#8217;s domain, and re-use those values in order to compute the function&#8217;s value at <em>all</em> domain values.
As implemented above, however, this trick makes function application more expensive, not less.
If <code>lm = linear f</code>, then each use of <code>lapply lm</code> can apply <code>f</code> to the value of every basis element, and then linearly combine results.</p>

<p>A simple trick fixes this efficiency problem: <em>memoize</em> the linear map.
We could do the memoization privately, e.g.,</p>

<p><div>
<pre class="haskell">linear f = memo <span style="color: green;">&#40;</span>f . basisValue<span style="color: green;">&#41;</span></pre>
</div></p>

<p>If <code>lm = linear f</code>, then no matter how many times <code>lapply lm</code> is applied, the function <code>f</code> can only get applied as many times as the dimension of the domain of <code>f</code>.</p>

<p>However, there are several other ways to make linear maps, and it would be easy to forget to memoize each combining form.
So, instead of the function representation above, I ensure that the function be memoized by representing it as a <a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="Blog post: &quot;Elegant memoization with functional memo tries&quot;">memo trie</a>.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> u :-* v = Basis u :-&gt;: v</pre>
</div></p>

<p>The conversion functions <code>linear</code> and <code>lapply</code> need just a little tweaking.
Split <code>memo</code> into its definition <code>untrie . trie</code>, and then move the second phase (<code>untrie</code>) into <code>lapply</code>.
We&#8217;ll also have to add <code>HasTrie</code> constraints:</p>

<p><div>
<pre class="haskell">linear :: <span style="color: green;">&#40;</span> VectorSpace u, VectorSpace v
          , HasBasis u, HasTrie <span style="color: green;">&#40;</span>Basis u<span style="color: green;">&#41;</span> <span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>u -&gt; v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>u :-* v<span style="color: green;">&#41;</span>
linear f = trie <span style="color: green;">&#40;</span>f . basisValue<span style="color: green;">&#41;</span>
&nbsp;
lapply :: <span style="color: green;">&#40;</span> VectorSpace u, VectorSpace v, Scalar u ~ Scalar v
          , HasBasis u, HasTrie <span style="color: green;">&#40;</span>Basis u<span style="color: green;">&#41;</span> <span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>u :-* v<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>u -&gt; v<span style="color: green;">&#41;</span>
lapply lm = linearCombo . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> <span style="color: green;">&#40;</span>untrie lm<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> . decompose</pre>
</div></p>

<p>Now we can build up linear maps conveniently and efficiently by using the operations on memo tries shown in <a href="http://conal.net/blog/posts/composing-memo-tries/" title="blog post">Composing memo tries</a>.
For instance, suppose that <code>h</code> is a linear function of two arguments (linear in <em>both</em>, not it <em>each</em>) and <code>m</code> and <code>n</code> are two linear maps.
Then <code>liftA2 h m n</code> is the linear function that applies <code>h</code> to the results of <code>m</code> and <code>n</code>.</p>

<p><div>
<pre class="haskell">lapply <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:liftA2"><span style="font-weight: bold;">liftA2</span></a> h m n<span style="color: green;">&#41;</span> a = h <span style="color: green;">&#40;</span>lapply m a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>lapply n a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Exploiting the applicative functor instance for functions, we get another formulation:</p>

<p><div>
<pre class="haskell">lapply <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:liftA2"><span style="font-weight: bold;">liftA2</span></a> h m n<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:liftA2"><span style="font-weight: bold;">liftA2</span></a> h <span style="color: green;">&#40;</span>lapply m<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>lapply n<span style="color: green;">&#41;</span></pre>
</div></p>

<p>In other words, the meaning of a <code>liftA2</code> is the <code>liftA2</code> of the meanings, as discussed in <a href="http://conal.net/blog/posts/simplifying-semantics-with-type-class-morphisms" title="blog post">Simplifying semantics with type class morphisms</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/simpler-more-efficient-functional-linear-maps/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vector space bases via type families</title>
		<link>http://conal.net/blog/posts/vector-space-bases-via-type-families/</link>
		<comments>http://conal.net/blog/posts/vector-space-bases-via-type-families/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 01:23:27 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[type family]]></category>
		<category><![CDATA[vector space]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=56</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Vector space bases via type families

Tags: vector space, type family

URL: http://conal.net/blog/posts/vector-space-bases-via-type-families/

-->

<!-- references -->

<!-- teaser -->

<p>A <a href="http://en.wikipedia.org/wiki/Basis_(linear_algebra)" title="Wikipedia article">basis</a> <em>B</em> of a vector space <em>V</em> is a subset <em>B</em> of <em>V</em>, such that the elements of <em>B</em> are linearly independent and span <em>V</em>.
That is to say, every element (vector) of <em>V</em> is a linear combination of elements of <em>B</em>, and no element of <em>B</em> is a linear combination of the other elements of <em>B</em>.
Moreover, every basis determines a unique decomposition of any member of <em>V</em> into coordinates relative to <em>B</em>.</p>

<p>This post gives a simple Haskell implementation for a canonical basis of a vector space, and a means of decomposing vectors into coordinates.
It uses <a href="http://research.microsoft.com/~simonpj/papers/assoc-types/" title="Collection of papers: &quot;Indexed type families&quot;">indexed type families</a> (associated types), and is quite general, despite its simplicity.</p>

<p>The Haskell module described here is part of the vector-space library (version 0.4 or later), which available on Hackage and a darcs repository.
See the <a href="http://haskell.org/haskellwiki/vector-space" title="Wiki page: vector-space">wiki page</a>, <a href="http://code.haskell.org/vector-space/doc/html/Data-ABasis.html" title="Interface documentation: Data.ABasis">interface documentation</a>, and <a href="http://code.haskell.org/vector-space/doc/html/src/Data-ABasis.html" title="Source module: Data.ABasis">source code</a>.
The library version described below (0.5 or later) relies on ghc 6.10.</p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2008-11-09: Tweaked comment above about version.</li>
<li>2008-02-09: just fiddling around</li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-56"></span></p>

<h3>Additive groups and vector spaces</h3>

<p>We&#8217;ll need a bit of preliminary before jumping into basis types.</p>

<p>An <em><a href="http://code.haskell.org/vector-space/doc/html/Data-AdditiveGroup.html" title="Interface documentation: Data.AdditiveGroup">additive group</a></em> has addition operation, with an identity (zero) and an additive inverse:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> AdditiveGroup v <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: green;">&#40;</span>^+^<span style="color: green;">&#41;</span>   :: v -&gt; v -&gt; v
  zeroV   :: v
  negateV :: v -&gt; v</pre>
</div></p>

<p>A <em><a href="http://code.haskell.org/vector-space/doc/html/Data-AVectorSpace.html" title="Interface documentation: Data.AVectorSpace">vector space</a></em> is an additive group with scalar multiplication, so it also has an associated type of scalars:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> AdditiveGroup v =&gt; VectorSpace v <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Scalar v :: *
  <span style="color: green;">&#40;</span>*^<span style="color: green;">&#41;</span> :: Scalar v -&gt; v -&gt; v</pre>
</div></p>

<p>This associated type could instead by written as a functional dependency (fundep).
In fact, the type family implementation in ghc 6.9 is not quite up to working with the code in this post, so the library contains a (6.9-friendly) version together with as a fundep (<code>Data.VectorSpace</code>) and the version given in this post (<code>Data.AVectorSpace</code>).
Sometime after ghc-6.10 is released, I will retire the fundep version and rename <code>AVectorSpace</code> to <code>VectorSpace</code>.
Similarly, the library temporarily contains <code>Data.ABasis</code>.</p>

<h3>Basis types</h3>

<p>Since Haskell doesn&#8217;t have subtyping, we can&#8217;t represent a basis type directly as a subset.
Instead, for an arbitrary vector space <code>v</code>, represent the (canonical) basis as an associated type, <code>Basis v</code>, and a function that interprets a basis representation as a vector.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">class</span> VectorSpace v =&gt; HasBasis v <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Basis v :: *
  basisValue   :: Basis v -&gt; v</pre>
</div></p>

<p>Another method extracts coordinates (coefficients) for a vector.
Each coordinate is associated with a basis element.</p>

<p><div>
<pre class="haskell">  decompose    :: v -&gt; <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span>Basis v, Scalar v<span style="color: green;">&#41;</span><span style="color: green;">&#93;</span></pre>
</div></p>

<p>We can also reverse the process, recomposing into a vector, by linearly combining the basis elements:</p>

<p><div>
<pre class="haskell">linearCombo :: VectorSpace v =&gt; <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span>v,Scalar v<span style="color: green;">&#41;</span><span style="color: green;">&#93;</span> -&gt; v
linearCombo ps = sumV <span style="color: green;">&#91;</span>s *^ v | <span style="color: green;">&#40;</span>v,s<span style="color: green;">&#41;</span> &lt;- ps<span style="color: green;">&#93;</span>
&nbsp;
recompose :: HasBasis v =&gt; <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span>Basis v, Scalar v<span style="color: green;">&#41;</span><span style="color: green;">&#93;</span> -&gt; v
recompose = linearCombo . <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> basisValue<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The defining property is</p>

<p><div>
<pre class="haskell">recompose . decompose == <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a></pre>
</div></p>

<div class="exercise">

<p><strong>Exercise</strong>: why might <code>decompose . recompose</code> not be the identity?  What if the decomposition were represented instead as a <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.html">finite map</a>?</p>

</div>

<h3>Primitive bases</h3>

<p>Any scalar field is also a vector space over itself.
For instance,</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> AdditiveGroup <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> <span style="color: #050; font-weight: bold;">where</span>
  zeroV   = <span style="color: red;">0.0</span>
  <span style="color: green;">&#40;</span>^+^<span style="color: green;">&#41;</span>   = <span style="color: green;">&#40;</span>+<span style="color: green;">&#41;</span>
  negateV = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:negate"><span style="font-weight: bold;">negate</span></a>
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> VectorSpace <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Scalar <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a>
  <span style="color: green;">&#40;</span>*^<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>*<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The canonical basis of a one-dimensional space has only one element, namely <code>1</code>, which can be represented with no information.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> HasBasis <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Basis <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> = <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
  basisValue <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>     = <span style="color: red;">1</span>
  decompose s       = <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span><span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>,s<span style="color: green;">&#41;</span><span style="color: green;">&#93;</span></pre>
</div></p>

<h3>Composing bases</h3>

<p>Pairs of additive groups form additive groups:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>AdditiveGroup u,AdditiveGroup v<span style="color: green;">&#41;</span>
      =&gt; AdditiveGroup <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  zeroV             = <span style="color: green;">&#40;</span>zeroV,zeroV<span style="color: green;">&#41;</span>
  <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> ^+^ <span style="color: green;">&#40;</span>u',v'<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>u^+^u',v^+^v'<span style="color: green;">&#41;</span>
  negateV <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span>     = <span style="color: green;">&#40;</span>negateV u,negateV v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Pairs of vector spaces, over the same scalar field, form vector spaces:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>VectorSpace u,VectorSpace v, Scalar u ~ Scalar v<span style="color: green;">&#41;</span>
      =&gt; VectorSpace <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Scalar <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> = Scalar u
  s *^ <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>s*^u,s*^v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Given vector spaces <code>u</code> and <code>v</code>, a basis representation for <code>(u,v)</code> will be one basis representation or the other, tagged with <code>Left</code> or <code>Right</code>:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>HasBasis u, HasBasis v, Scalar u ~ Scalar v<span style="color: green;">&#41;</span>
      =&gt; HasBasis <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Basis <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> = Basis u `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a>` Basis v</pre>
</div></p>

<p>The basis vectors themselves will be <code>(ub,0)</code> or <code>(0,vb)</code>, where <code>ub</code> is a basis vector for <code>u</code>, and <code>vb</code> is a basis vector for <code>v</code>.
As expected then, the dimensionality of the cross product is the sum of the dimensions.</p>

<p><div>
<pre class="haskell">  basisValue <span style="color: green;">&#40;</span>Left  a<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>basisValue a, zeroV<span style="color: green;">&#41;</span>
  basisValue <span style="color: green;">&#40;</span>Right b<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>zeroV, basisValue b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The decomposition of a vector <code>(u,v)</code> contains left-tagged decompositions of <code>u</code> and right-tagged decompositions of <code>v</code>.</p>

<p><div>
<pre class="haskell">  decompose <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> = decomp2 Left u ++ decomp2 Right v</pre>
</div></p>

<p>where</p>

<p><div>
<pre class="haskell">decomp2 :: HasBasis w =&gt; <span style="color: green;">&#40;</span>Basis w -&gt; b<span style="color: green;">&#41;</span> -&gt; w -&gt; <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span>Scalar w, b<span style="color: green;">&#41;</span><span style="color: green;">&#93;</span>
decomp2 inject = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Arrow.html#v:first"><span style="font-weight: bold;">first</span></a> inject<span style="color: green;">&#41;</span> . decompose</pre>
</div></p>

<p>Triples etc, can be handled similarly.
Instead, the library implementation reduces them to the pair case:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span> HasBasis u, s ~ Scalar u
         , HasBasis v, s ~ Scalar v
         , HasBasis w, s ~ Scalar w <span style="color: green;">&#41;</span>
      =&gt; HasBasis <span style="color: green;">&#40;</span>u,v,w<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Basis <span style="color: green;">&#40;</span>u,v,w<span style="color: green;">&#41;</span> = Basis <span style="color: green;">&#40;</span>u,<span style="color: green;">&#40;</span>v,w<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
  ...</pre>
</div></p>

<p><strong>Exercise</strong>: complete this instance definition (without peeking).</p>

<h3>Bases in spaces</h3>

<p>What about other vector spaces, particularly infinite dimensional ones?
The result type for <code>decompose</code> is not convenient:</p>

<p><div>
<pre class="haskell">decompose :: v -&gt; <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span>Basis v, Scalar v<span style="color: green;">&#41;</span><span style="color: green;">&#93;</span></pre>
</div></p>

<p>Moreover, its definition for pair types would have to be changed, e.g., to use interleaving instead of append.
On the other hand, this type can be thought of as an association list, representing <code>Basis v -&gt; Scalar v</code>.
Instead, we might use the function representation directly:</p>

<p><div>
<pre class="haskell">decompose :: v -&gt; <span style="color: green;">&#40;</span>Basis v -&gt; Scalar v<span style="color: green;">&#41;</span></pre>
</div></p>

<p>In that case, the definition of <code>decompose</code> on pairs is</p>

<p><div>
<pre class="haskell">decompose <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> = decompose u `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:either"><span style="font-weight: bold;">either</span></a>` decompose v</pre>
</div></p>

<p>which beautifully mirrors the basis type definition:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">type</span> Basis <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> = Basis u `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a>` Basis v</pre>
</div></p>

<p>I guess we&#8217;d have to somehow extend the definition of <code>recompose</code> as well, or avoid it.</p>

<p>One example of an infinite dimensional vector space is a function over an infinite domain.
The additive group and vector space instances follow a standard form for applicative functors applied to an additive group or vector space.
In this case, the applicative functor is <code>((-&gt;) a)</code>.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> AdditiveGroup v =&gt; AdditiveGroup <span style="color: green;">&#40;</span>a -&gt; v<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  zeroV   = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:pure"><span style="font-weight: bold;">pure</span></a>   zeroV
  <span style="color: green;">&#40;</span>^+^<span style="color: green;">&#41;</span>   = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html#v:liftA2"><span style="font-weight: bold;">liftA2</span></a> <span style="color: green;">&#40;</span>^+^<span style="color: green;">&#41;</span>
  negateV = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a>   negateV
&nbsp;
<span style="color: #050; font-weight: bold;">instance</span> VectorSpace v =&gt; VectorSpace <span style="color: green;">&#40;</span>a -&gt; v<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Scalar <span style="color: green;">&#40;</span>a -&gt; v<span style="color: green;">&#41;</span> = Scalar v
  <span style="color: green;">&#40;</span>*^<span style="color: green;">&#41;</span> s = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>*^<span style="color: green;">&#41;</span> s<span style="color: green;">&#41;</span></pre>
</div></p>

<p>As a basis for a function space <code>a-&gt;u</code>, let&#8217;s use the subset of functions that map one domain value to some basis vector for <code>u</code> and map all other domain values to zero.
By linearly combining these functions, we can construct <em>any</em> function in <code>a-&gt;u</code> that is nonzero for finitely many domain values.
If we stretch the notion of linear combinations beyond finite combinations, perhaps we can go further and cover at least the countably infinite domain types.</p>

<p>To represent these functions, it suffices to record the choice of domain element and the representation of the corresponding basis vector for <code>u</code>:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Eq"><span style="color: #833; font-weight: bold;">Eq</span></a> a, HasBasis u<span style="color: green;">&#41;</span> =&gt; HasBasis <span style="color: green;">&#40;</span>a -&gt; u<span style="color: green;">&#41;</span> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">type</span> Basis <span style="color: green;">&#40;</span>a -&gt; u<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>a, Basis u<span style="color: green;">&#41;</span>
&nbsp;
  basisValue <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> a' | a == a'   = basisValue b
                      | <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:otherwise"><span style="font-weight: bold;">otherwise</span></a> = zeroV</pre>
</div></p>

<p>The actual implementation is a bit more efficient, avoiding recomputation of <code>basisValue b</code> for each <code>a'</code>.</p>

<p>Decomposing a function into its coordinates is even simpler:</p>

<p><div>
<pre class="haskell">  decompose g <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> = decompose <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span> b</pre>
</div></p>

<h3>Some isomorphisms</h3>

<p>This instance rule for functions will be applied repeatedly for curried functions.
For instance, <code>Basis (a -&gt; b -&gt; u) == (a, (b, Basis u))</code>.
The isomorphic uncurried form has an isomorphic basis: <code>Basis ((a,b) -&gt; u) == ((a,b), Basis u)</code>.</p>

<p>Pairing in the range instead of domain gives rise to another pair of isomorphisms:</p>

<p><div>
<pre class="haskell">Basis <span style="color: green;">&#40;</span>a -&gt; <span style="color: green;">&#40;</span>b,c<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> == <span style="color: green;">&#40;</span>a, Basis b `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a>` Basis c<span style="color: green;">&#41;</span>
&nbsp;
Basis <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a -&gt; b, a -&gt; c<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> == <span style="color: green;">&#40;</span>a, Basis b<span style="color: green;">&#41;</span> `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a>` <span style="color: green;">&#40;</span>a, Basis c<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The rules for basis types look like logarithms, especially if we add a basis for <code>()</code>:</p>

<p><div>
<pre class="haskell">  <span style="color: #050; font-weight: bold;">type</span> Basis <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> = Void
&nbsp;
  <span style="color: #050; font-weight: bold;">type</span> Basis <span style="color: green;">&#40;</span>u,v<span style="color: green;">&#41;</span> = Basis u `<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Either"><span style="color: #833; font-weight: bold;">Either</span></a>` Basis v
&nbsp;
  <span style="color: #050; font-weight: bold;">type</span> Basis <span style="color: green;">&#40;</span>a -&gt; u<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>a, Basis u<span style="color: green;">&#41;</span></pre>
</div></p>

<p>Compare with:</p>

<p><div class=latex><img src='http://conal.net/blog/wp-content/latex/55a/55a3af2c856a2d1c288ff9b772f992d4-ffffff000000.png' alt='\log 1 = 0' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/f39/f39335e2b42b7ccdc2a819f438fdf703-ffffff000000.png' alt='\log (u \times v) = \log u + \log v' class='latex' /></div>
<div class=latex><img src='http://conal.net/blog/wp-content/latex/fcd/fcd90ab1b3200b1673b7d3070f42420c-ffffff000000.png' alt='\log (u ^ a) = a \times \log u' class='latex' /></div></p>

<p>The rules are also essentially the same as the ones used for <a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">memo tries</a>, but phrased in terms of logarithms instead of (explicit) exponents.</p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/vector-space-bases-via-type-families/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Functional linear maps</title>
		<link>http://conal.net/blog/posts/functional-linear-maps/</link>
		<comments>http://conal.net/blog/posts/functional-linear-maps/#comments</comments>
		<pubDate>Wed, 04 Jun 2008 05:49:20 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[derivative]]></category>
		<category><![CDATA[linear map]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[type family]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=51</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Functional linear maps

Tags: linear maps, math, derivatives, type families

URL: http://conal.net/blog/posts/functional-linear-maps/

-->

<!-- references -->

<!-- teaser -->

<p>Two <a href="http://conal.net/blog/posts/what-is-a-derivative-really/" title="Blog post: &quot;What is a derivative, really?&quot;">earlier</a> <a href="http://conal.net/blog/posts/higher-dimensional-higher-order-derivatives-functionally/" title="Blog post: &quot;Higher-dimensional, higher-order derivatives, functionally&quot;">posts</a> described a simple and general notion of <em>derivative</em> that unifies the many concrete notions taught in traditional calculus courses.
All of those variations turn out to be concrete representations of the single abstract notion of a <em>linear map</em>.
Correspondingly, the various forms of mulitplication in chain rules all turn out to be implementations of <em>composition</em> of linear maps.
For simplicity, I suggested a direct implementation of linear maps as functions.
Unfortunately, that direct representation thwarts efficiency, since functions, unlike data structures, do not cache by default.</p>

<p>This post presents a <em>data</em> representation of linear maps that makes crucial use of (a) linearity and (b) the recently added language feature <em>indexed type families</em> (&#8220;associated types&#8221;).</p>

<p>For a while now, I&#8217;ve wondered if a library for linear maps could replace and generalize matrix libraries.
After all, matrices represent of a restricted class of linear maps.
Unlike conventional matrix libraries, however, the linear map library described in this post captures matrix/linear-map dimensions via <em>static typing</em>.
The composition function defined below statically enforces the conformability property required of matrix multiplication (which implements linear map composition).
Likewise, conformance for addition of linear maps is also enforced simply and statically.
Moreover, with sufficiently sophisticated coaxing of the Haskell compiler, of the sort <a href="http://reddit.com/goto?id=6lx36" title="Blog post: &quot;Haskell as fast as C: working at a high altitude for low level performance&quot;">Don Stewart does</a>, perhaps a library like this one could also have terrific performance.  (It doesn&#8217;t yet.)</p>

<p>You can read and try out the code for this post in the module <a href="http://code.haskell.org/vector-space/doc/html/src/Data-LinearMap.html" title="Source module: Data.LinearMap">Data.LinearMap</a> in version 0.2.0 or later of the <a href="http://haskell.org/haskellwiki/vector-space" title="Library wiki page: &quot;vector-space&quot;">vector-space</a> package.
That module also contains an implementation of linear map composition, as well as <code>Functor</code>-like and <code>Applicative</code>-like operations.
<a href="http://www.unsafeperformio.com/index.php" title="Andy Gill's home page">Andy Gill</a> has been helping me get to the bottom of some some severe performance problems, apparently involving huge amounts of redundant dictionary creation.</p>

<p><strong>Edits</strong>:</p>

<ul>
<li>2008-06-04: Brief explanation of the associated data type declaration.</li>
</ul>

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-51"></span></p>

<h3>Linear maps</h3>

<p>Semantically, a <em>linear map</em> is a function <code>f :: a -&gt; b</code> such that, for all scalar values <code>c</code> and &#8220;vectors&#8221; <code>u, v :: a</code>, the following properties hold:</p>

<p><div>
<pre class="haskell">f <span style="color: green;">&#40;</span>c *^ u<span style="color: green;">&#41;</span>  == c *^ f u
f <span style="color: green;">&#40;</span>u ^+^ v<span style="color: green;">&#41;</span> == f u ^+^ f v</pre>
</div></p>

<p>where <code>(*^)</code> and <code>(^+^)</code> are scalar multiplication and vector addition.
(See <code>VectorSpace</code> details in a <a href="http://conal.net/blog/posts/higher-dimensional-higher-order-derivatives-functionally/" title="Blog post: &quot;Higher-dimensional, higher-order derivatives, functionally&quot;">previous post</a>.)</p>

<p>Although the semantics of a linear map will be a function, the representation will be a data structure.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">data</span> a :-* b = ...</pre>
</div></p>

<p>The semantic function is</p>

<p><div>
<pre class="haskell">lapply :: <span style="color: green;">&#40;</span>LMapDom a s, VectorSpace b s<span style="color: green;">&#41;</span> =&gt;
          <span style="color: green;">&#40;</span>a :-* b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span>  <span style="color: #5d478b; font-style: italic;">-- result will be linear</span></pre>
</div></p>

<p>The first constraint says that we know how to represent linear maps whose domain is the vector space <code>a</code>, which has the associated scalar field <code>s</code>.
The second constraint say that <code>b</code> must be a vector space over that same scalar field.</p>

<p>Conversely, there is also a function to turn any linear function into a linear map:</p>

<p><div>
<pre class="haskell">linear :: LMapDom a s =&gt; <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a :-* b<span style="color: green;">&#41;</span>  <span style="color: #5d478b; font-style: italic;">-- argument must be linear</span></pre>
</div></p>

<p>These two functions and the linear map data type are packaged up as the <code>LMapDom</code> type class:</p>

<p><div>
<pre class="haskell"><span style="color: #5d478b; font-style: italic;">-- | Domain of a linear map.</span>
<span style="color: #050; font-weight: bold;">class</span> VectorSpace a s =&gt; LMapDom a s | a -&gt; s <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #5d478b; font-style: italic;">-- | Linear map type</span>
  <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>:-*<span style="color: green;">&#41;</span> a :: * -&gt; *
  <span style="color: #5d478b; font-style: italic;">-- | Linear map as function</span>
  lapply :: VectorSpace b s =&gt; <span style="color: green;">&#40;</span>a :-* b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span>
  <span style="color: #5d478b; font-style: italic;">-- | Function (assumed linear) as linear map.</span>
  linear :: <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a :-* b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>The <code>data</code> definition means that the data type <code>(a :-* b)</code> (of linear maps from <code>a</code> to <code>b</code>) is has a variety of representations, each one associated with a type <code>a</code>.</p>

<p>These two conversion functions are required to be inverses:</p>

<p><div>
<pre class="haskell"><span style="color: #5d478b; font-style: italic;">{-# RULES
&nbsp;
&quot;linear.lapply&quot;   forall m. linear (lapply m) = m
&nbsp;
&quot;lapply.linear&quot;   forall f. lapply (linear f) = f
&nbsp;
 #-}</span></pre>
</div></p>

<h3>Scalar domains</h3>

<p>Consider a linear function <code>f</code> over a scalar domain.
Then</p>

<p><div>
<pre class="haskell">f s == f <span style="color: green;">&#40;</span>s *^ <span style="color: red;">1</span><span style="color: green;">&#41;</span>
    == s *^ f <span style="color: red;">1</span>  <span style="color: #5d478b; font-style: italic;">-- by linearity</span></pre>
</div></p>

<p>Therefore, <code>f</code> is fully determined by its value at <code>1</code>, and so an adequate representation of <code>f</code> is then simply the value <code>f 1</code>.</p>

<p>This observation leads to <code>LMapDom</code> instances like the following:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> LMapDom <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">data</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> :-* o  = DoubleL o
  lapply <span style="color: green;">&#40;</span>DoubleL o<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>*^ o<span style="color: green;">&#41;</span>
  linear f           = DoubleL <span style="color: green;">&#40;</span>f <span style="color: red;">1</span><span style="color: green;">&#41;</span></pre>
</div></p>

<h3>Non-scalar domains</h3>

<p>Maps over non-scalar domains are a little trickier.
Consider a linear function <code>f</code> over a domain of pairs of scalar values.
Then</p>

<p><div>
<pre class="haskell">f <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> == f <span style="color: green;">&#40;</span>a *^ <span style="color: green;">&#40;</span><span style="color: red;">1</span>,<span style="color: red;">0</span><span style="color: green;">&#41;</span> ^+^ b *^ <span style="color: green;">&#40;</span><span style="color: red;">0</span>,<span style="color: red;">1</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
        == f <span style="color: green;">&#40;</span>a *^ <span style="color: green;">&#40;</span><span style="color: red;">1</span>,<span style="color: red;">0</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> ^+^ f <span style="color: green;">&#40;</span>b *^ <span style="color: green;">&#40;</span><span style="color: red;">0</span>,<span style="color: red;">1</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>  <span style="color: #5d478b; font-style: italic;">-- linearity</span>
        == a *^ f <span style="color: green;">&#40;</span><span style="color: red;">1</span>,<span style="color: red;">0</span><span style="color: green;">&#41;</span> ^+^ b *^ f <span style="color: green;">&#40;</span><span style="color: red;">0</span>,<span style="color: red;">1</span><span style="color: green;">&#41;</span>      <span style="color: #5d478b; font-style: italic;">-- linearity twice more</span></pre>
</div></p>

<p>So <code>f</code> is determined by <code>f (1,0)</code> and <code>f (0,1)</code> and thus can be represented by those two values.</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> LMapDom <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a>,<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a><span style="color: green;">&#41;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a> <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a>,<a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Double"><span style="color: #833; font-weight: bold;">Double</span></a><span style="color: green;">&#41;</span> :-* o = PairD o o
  PairD ao bo `lapply` <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> = a *^ ao ^+^ b *^ bo
  linear f = PairD <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span><span style="color: red;">0</span>,<span style="color: red;">1</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span><span style="color: red;">1</span>,<span style="color: red;">0</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>and similarly for triples, etc.</p>

<p>This definition works fine, but I want something compositional.
I&#8217;d like linear maps over pairs of pairs and so on.</p>

<h3>Composing domains</h3>

<p>We can still use part of our linearity property.  Using <code>zeroV</code> as the zero vector for arbitrary vector spaces,</p>

<p><div>
<pre class="haskell">f <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> == f <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a,zeroV<span style="color: green;">&#41;</span> ^+^ <span style="color: green;">&#40;</span>zeroV,b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
        == f <span style="color: green;">&#40;</span>a,zeroV<span style="color: green;">&#41;</span> ^+^ f <span style="color: green;">&#40;</span>zeroV,b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>We see that <code>f</code> is determined by its behavior when either argument is zero.</p>

<p>In other words, <code>f</code> can be reconstructed from two other functions over simpler domains:</p>

<p><div>
<pre class="haskell">fa a = f <span style="color: green;">&#40;</span>a,zeroV<span style="color: green;">&#41;</span>
fb b = f <span style="color: green;">&#40;</span>zeroV,b<span style="color: green;">&#41;</span></pre>
</div></p>

<p>If <code>f :: (a,b) -&gt; o</code>, then <code>fa :: a -&gt; o</code> and <code>fb :: b -&gt; o</code>.</p>

<p>Exercise: show that <code>fa</code> and <code>fb</code> are linear if <code>f</code> is.
We can thus reduce the problem of representing the linear function <code>f</code> to the problems of representing <code>fa</code> and <code>fb</code>.
This insight is captured in the following <code>LMapDom</code> instance:</p>

<p><div>
<pre class="haskell"><span style="color: #050; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>LMapDom a s, LMapDom b s<span style="color: green;">&#41;</span> =&gt; LMapDom <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> s <span style="color: #050; font-weight: bold;">where</span>
  <span style="color: #050; font-weight: bold;">data</span> <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> :-* o = PairL <span style="color: green;">&#40;</span>a :-* o<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>b :-* o<span style="color: green;">&#41;</span>
  PairL ao bo `lapply` <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> = ao `lapply` a ^+^ bo `lapply` b
  linear f = PairL <span style="color: green;">&#40;</span>linear <span style="color: green;">&#40;</span>\ a -&gt; f <span style="color: green;">&#40;</span>a,zeroV<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
                   <span style="color: green;">&#40;</span>linear <span style="color: green;">&#40;</span>\ b -&gt; f <span style="color: green;">&#40;</span>zeroV,b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>Of course, there are similar instances for triples, etc, as well as for tuple variants with strict fields, such as OpenGL&#8217;s <code>Vector2</code> and <code>Vector3</code> types.</p>

<h3>What have we done?</h3>

<p>If you&#8217;ve studied linear algebra, you may be thinking now about the idea of a <em>basis</em> of a vector space.
A basis is a minimal set of vectors that can be combined linearly to cover the entire vector space.
Any linear map is determined by its behavior on any basis.
For scalars, the set <code>{1}</code> is a basis, while for pairs of scalars, <code>{(1,0), (0,1)}</code> is a basis.
It is not just coincidental that exactly these basis vectors showed up in the definitions of <code>linear</code> for <code>Double</code> and <code>(Double,Double)</code>.</p>

<p>In the general pairing instance of <code>LMapDom</code> above, bases are built up recursively.
Each recursive call to <code>linear</code> results in a data structure that holds the values of <code>fa</code> over a basis for <code>a</code> and the values of <code>fb</code> over a basis for <code>b</code>.
Each of those basis vectors corresponds to a basis vector for <code>(a,b)</code>, by <code>zeroV</code>-padding.</p>

<p>The <em>dimension</em> of a vector space is the number of elements in a basis (which is independent of the particular choice of basis).
For vector space types <code>a</code> and <code>b</code>,</p>

<p><div>
<pre class="haskell">dimension <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> == dimension a + dimension b</pre>
</div></p>

<p>which corresponds to the fact that our linear map representation (as built by <code>linear</code>) contains samples for each basis element of <code>a</code>, <em>plus</em> samples for each basis element of <code>b</code> (all <code>zeroV</code>-padded).</p>

<h3>Working with linear maps</h3>

<p>Besides the instances above for creating and applying linear maps, what else can we do?
For starters, let&#8217;s define the identity linear map.
Since the identity function is already linear, simply convert it to a linear map:</p>

<p><div>
<pre class="haskell">idL :: LMapDom a s =&gt; a :-* a
idL = linear <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a></pre>
</div></p>

<p>Another very useful tool is transforming a linear map by transforming a linear function.</p>

<p><div>
<pre class="haskell">inL :: <span style="color: green;">&#40;</span>LMapDom c s, VectorSpace b s', LMapDom a s'<span style="color: green;">&#41;</span> =&gt;
        <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>c -&gt; d<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a :-* b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>c :-* d<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
inL h = linear . h . lapply</pre>
</div></p>

<p>where the higher-order function <code>h</code> is assumed to map linear functions to linear functions.</p>

<p>We don&#8217;t have to stop at <em>unary</em> transformations of linear functions.</p>

<p><div>
<pre class="haskell"><span style="color: #5d478b; font-style: italic;">-- | Transform a linear maps by transforming linear functions.</span>
inL2 :: <span style="color: green;">&#40;</span> LMapDom c s, VectorSpace b s', LMapDom a s'
        , LMapDom e s, VectorSpace d s <span style="color: green;">&#41;</span> =&gt;
        <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a  -&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>c  -&gt; d<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>e  -&gt; f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
     -&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a :-* b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>c :-* d<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>e :-* f<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
inL2 h = inL . h . lapply</pre>
</div></p>

<p>The type constraints are starting to get hairy.
Fortunately, they&#8217;re entirely inferred by the compiler.</p>

<p>Let&#8217;s do some inlining and simplification to see what goes on inside <code>inL2</code>:</p>

<p><div>
<pre class="haskell">inL2 h m n
  == <span style="color: green;">&#40;</span>inL . h . lapply<span style="color: green;">&#41;</span> m n                <span style="color: #5d478b; font-style: italic;">-- inline inL2</span>
  == inL <span style="color: green;">&#40;</span>h <span style="color: green;">&#40;</span>lapply m<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> n                  <span style="color: #5d478b; font-style: italic;">-- inline (.)</span>
  == <span style="color: green;">&#40;</span>linear . <span style="color: green;">&#40;</span>h <span style="color: green;">&#40;</span>lapply m<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> . lapply<span style="color: green;">&#41;</span> n  <span style="color: #5d478b; font-style: italic;">-- inline inL</span>
  == linear <span style="color: green;">&#40;</span>h <span style="color: green;">&#40;</span>lapply m<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>lapply n<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>      <span style="color: #5d478b; font-style: italic;">-- inline (.)</span></pre>
</div></p>

<p>Ternary transformations are defined similarly.
I&#8217;ll spare you the type constraints this time.</p>

<p><div>
<pre class="haskell">inL3 :: <span style="color: green;">&#40;</span> ... <span style="color: green;">&#41;</span> =&gt;
        <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a  -&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>c  -&gt; d<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>e  -&gt; f<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>p  -&gt; q<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
     -&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a :-* b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>c :-* d<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>e :-* f<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>p :-* q<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
inL3 h = inL2 . h . lapply</pre>
</div></p>

<p>Look what happens when these operations are composed.
As an example,</p>

<p><div>
<pre class="haskell">inL h . inL g
  == <span style="color: green;">&#40;</span>linear . h . lapply<span style="color: green;">&#41;</span> . <span style="color: green;">&#40;</span>linear . g . lapply<span style="color: green;">&#41;</span>
  == linear . h . lapply . linear . g . lapply    <span style="color: #5d478b; font-style: italic;">-- associativity of (.)</span>
  == linear . h . g . lapply                      <span style="color: #5d478b; font-style: italic;">-- rule &quot;lapply.linear&quot;</span>
  == inL <span style="color: green;">&#40;</span>h . g<span style="color: green;">&#41;</span></pre>
</div></p>

<p>This transformation is not actually happening in the compiler yet.
The &#8220;lapply.linear&#8221; rule is not firing, and I don&#8217;t know why.
I&#8217;d appreciate suggestions.</p>

<p>There are a few more operations defined in <a href="http://code.haskell.org/vector-space/doc/html/src/Data-LinearMap.html" title="Source module: Data.LinearMap">Data.LinearMap</a>.
I&#8217;ll end with this simple, general definition of composition of linear maps:</p>

<p><div>
<pre class="haskell"><span style="color: #5d478b; font-style: italic;">-- | Compose linear maps</span>
<span style="color: green;">&#40;</span>.*<span style="color: green;">&#41;</span> :: <span style="color: green;">&#40;</span>VectorSpace c s, LMapDom b s, LMapDom a s<span style="color: green;">&#41;</span> =&gt;
        <span style="color: green;">&#40;</span>b :-* c<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a :-* b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a :-* c<span style="color: green;">&#41;</span>
<span style="color: green;">&#40;</span>.*<span style="color: green;">&#41;</span> = inL2 <span style="color: green;">&#40;</span>.<span style="color: green;">&#41;</span></pre>
</div></p>

<h3>Derivative towers again</h3>

<p>A similar, but recursive, definition is used in the new definition of the the general chain rule for infinite derivative towers, updated since the post <em><a href="http://conal.net/blog/posts/higher-dimensional-higher-order-derivatives-functionally/" title="Blog post: &quot;Higher-dimensional, higher-order derivatives, functionally&quot;">Higher-dimensional, higher-order derivatives, functionally</a></em>.</p>

<p><div>
<pre class="haskell"><span style="color: green;">&#40;</span>@.<span style="color: green;">&#41;</span> :: <span style="color: green;">&#40;</span>LMapDom b s, LMapDom a s, VectorSpace c s<span style="color: green;">&#41;</span> =&gt;
        <span style="color: green;">&#40;</span>b :~&gt; c<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a :~&gt; b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a :~&gt; c<span style="color: green;">&#41;</span>
<span style="color: green;">&#40;</span>h @. g<span style="color: green;">&#41;</span> a0 = D c0 <span style="color: green;">&#40;</span>inL2 <span style="color: green;">&#40;</span>@.<span style="color: green;">&#41;</span> c' b'<span style="color: green;">&#41;</span>
  <span style="color: #050; font-weight: bold;">where</span>
    D b0 b' = g a0
    D c0 c' = h b0</pre>
</div></p>
]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/functional-linear-maps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
