docs/README_md.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>README - RDoc Documentation</title>
<script type="text/javascript">
var rdoc_rel_prefix = "./";
</script>
<script src="./js/jquery.js"></script>
<script src="./js/darkfish.js"></script>
<link href="./css/fonts.css" rel="stylesheet">
<link href="./css/rdoc.css" rel="stylesheet">
<body id="top" role="document" class="file">
<nav role="navigation">
<div id="project-navigation">
<div id="home-section" role="region" title="Quick navigation" class="nav-section">
<h2>
<a href="./index.html" rel="home">Home</a>
</h2>
<div id="table-of-contents-navigation">
<a href="./table_of_contents.html#pages">Pages</a>
<a href="./table_of_contents.html#classes">Classes</a>
<a href="./table_of_contents.html#methods">Methods</a>
</div>
</div>
<div id="search-section" role="search" class="project-section initially-hidden">
<form action="#" method="get" accept-charset="utf-8">
<div id="search-field-wrapper">
<input id="search-field" role="combobox" aria-label="Search"
aria-autocomplete="list" aria-controls="search-results"
type="text" name="search" placeholder="Search" spellcheck="false"
title="Type to search, Up and Down to navigate, Enter to load">
</div>
<ul id="search-results" aria-label="Search Results"
aria-busy="false" aria-expanded="false"
aria-atomic="false" class="initially-hidden"></ul>
</form>
</div>
</div>
<div class="nav-section">
<h3>Table of Contents</h3>
<ul class="link-list" role="directory">
<li><a href="#label-Mr.CAS">Mr.CAS</a>
<li><a href="#label-Introduction">Introduction</a>
<li><a href="#label-Module+Structure">Module Structure</a>
<li><a href="#label-Example">Example</a>
<li><a href="#label-Execution">Execution</a>
<li><a href="#label-Installation">Installation</a>
<li><a href="#label-Define+a+function">Define a function</a>
<li><a href="#label-Derivatives">Derivatives</a>
<li><a href="#label-Substitutions">Substitutions</a>
<li><a href="#label-Meta-Programming+-28a+Newton+algorithm...-29">Meta-Programming (a Newton algorithm…)</a>
<li><a href="#label-Disclaimer">Disclaimer</a>
<li><a href="#label-Full+example+code">Full example code</a>
<li><a href="#label-To+do">To do</a>
<li><a href="#label-Simple">Simple</a>
<li><a href="#label-Complex">Complex</a>
<li><a href="#label-Extremely+complex">Extremely complex</a>
</ul>
</div>
<div id="project-metadata">
<div id="fileindex-section" class="nav-section">
<h3>Pages</h3>
<ul class="link-list">
<li><a href="./README_md.html">README</a>
</ul>
</div>
</div>
</nav>
<main role="main" aria-label="Page README.md">
<h1 id="label-Mr.CAS">Mr.CAS<span><a href="#label-Mr.CAS">¶</a> <a href="#top">↑</a></span></h1>
<p><a href="https://badge.fury.io/rb/Mr.CAS"><img
src="https://badge.fury.io/rb/Mr.CAS.svg"></a> <a
href="https://codeclimate.com/github/MatteoRagni/cas-rb"><img
src="https://codeclimate.com/github/MatteoRagni/cas-rb/badges/gpa.svg"></a>
<a href="https://travis-ci.org/MatteoRagni/cas-rb"><img
src="https://travis-ci.org/MatteoRagni/cas-rb.svg?branch=master"></a></p>
<h2 id="label-Introduction">Introduction<span><a href="#label-Introduction">¶</a> <a href="#top">↑</a></span></h2>
<p>An extremely simple graph, that handles only differentiation and
simplification with one step ahead in the graph.</p>
<h2 id="label-Module+Structure">Module Structure<span><a href="#label-Module+Structure">¶</a> <a href="#top">↑</a></span></h2>
<p><img
src="https://gist.githubusercontent.com/MatteoRagni/639294457d97858bbb3cee2ffaf782dc/raw/2854e8877f2106307bfa190649e4253c70282139/graphviz.png"></p>
<h2 id="label-Example">Example<span><a href="#label-Example">¶</a> <a href="#top">↑</a></span></h2>
<p>Given the function of Rosenbrock, find the optimum of such a function.</p>
<h2 id="label-Execution">Execution<span><a href="#label-Execution">¶</a> <a href="#top">↑</a></span></h2>
<h3 id="label-Installation">Installation<span><a href="#label-Installation">¶</a> <a href="#top">↑</a></span></h3>
<p>First of all is necessary to install and load the <code>Mr.CAS</code> gem.</p>
<pre class="ruby"><span class="ruby-identifier">gem</span> <span class="ruby-identifier">install</span> <span class="ruby-constant">Mr</span>.<span class="ruby-constant">CAS</span>
</pre>
<pre class="ruby"><span class="ruby-identifier">require</span> <span class="ruby-string">'Mr.CAS'</span>
</pre>
<h3 id="label-Define+a+function">Define a function<span><a href="#label-Define+a+function">¶</a> <a href="#top">↑</a></span></h3>
<p>Now we can define the Rosenbrock function, that has two variable
(<code>x</code> and <code>y</code>) and two constants (<code>a</code> and
<code>b</code>, with the default value on 1 and 100 in this case). The
variable <code>f</code> will contain our function:</p>
<pre class="ruby"><span class="ruby-identifier">x</span>, <span class="ruby-identifier">y</span> = <span class="ruby-constant">CAS</span><span class="ruby-operator">::</span><span class="ruby-identifier">vars</span> :<span class="ruby-identifier">x</span>, :<span class="ruby-identifier">y</span>
<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span> = <span class="ruby-constant">CAS</span><span class="ruby-operator">::</span><span class="ruby-identifier">const</span> <span class="ruby-value">1.0</span>, <span class="ruby-value">100.0</span>
<span class="ruby-identifier">f</span> = ((<span class="ruby-identifier">a</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">x</span>) <span class="ruby-operator">**</span> <span class="ruby-value">2</span>) <span class="ruby-operator">+</span> <span class="ruby-identifier">b</span> <span class="ruby-operator">*</span> ((<span class="ruby-identifier">y</span> <span class="ruby-operator">-</span> (<span class="ruby-identifier">x</span> <span class="ruby-operator">**</span> <span class="ruby-value">2</span>)) <span class="ruby-operator">**</span> <span class="ruby-value">2</span>)
</pre>
<p>We can print this function as follows:</p>
<pre class="ruby"><span class="ruby-identifier">puts</span> <span class="ruby-node">"f = #{f}"</span>
<span class="ruby-comment"># => ((1.0 - x)^2 + (100.0 * (y - x^2)^2))</span>
</pre>
<h3 id="label-Derivatives">Derivatives<span><a href="#label-Derivatives">¶</a> <a href="#top">↑</a></span></h3>
<p>To find the minimum we need to find the point in which the gradient of such
a function is equal to zero</p>
<p>The two derivatives are:</p>
<pre class="ruby"><span class="ruby-identifier">dfx</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">diff</span>(<span class="ruby-identifier">x</span>).<span class="ruby-identifier">simplify</span>
<span class="ruby-identifier">dfy</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">diff</span>(<span class="ruby-identifier">y</span>).<span class="ruby-identifier">simplify</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"df/dx = #{dfx}"</span>
<span class="ruby-comment"># => df/dx = ((((1 - x) * 2) * -1) + ((((y - x^2) * 2) * -(x * 2)) * 100.0))</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"df/dy = #{dfy}"</span>
<span class="ruby-comment"># => df/dy = (((y - x^2) * 2) * 100.0)</span>
</pre>
<h3 id="label-Substitutions">Substitutions<span><a href="#label-Substitutions">¶</a> <a href="#top">↑</a></span></h3>
<p>Now, from the second it is quite evident that</p>
<pre>y = x^2 = g(x)</pre>
<p>and thus we can perform on the first a substitution:</p>
<pre class="ruby"><span class="ruby-identifier">g</span> = (<span class="ruby-identifier">x</span> <span class="ruby-operator">**</span> <span class="ruby-value">2</span>)
<span class="ruby-identifier">dfx</span> = <span class="ruby-identifier">dfx</span>.<span class="ruby-identifier">subs</span>({<span class="ruby-identifier">y</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">g</span>})
<span class="ruby-identifier">puts</span> <span class="ruby-node">"df/dx = #{dfx}"</span>
<span class="ruby-comment"># => df/dx = (((1 - x) * 2) * -1)</span>
</pre>
<h3 id="label-Meta-Programming+-28a+Newton+algorithm...-29">Meta-Programming (a Newton algorithm…)<span><a href="#label-Meta-Programming+-28a+Newton+algorithm...-29">¶</a> <a href="#top">↑</a></span></h3>
<p>That is something quite simple to solve (x = 1). Let's use this
formulation for some meta-programming anyway! The stationary point is in
the root of the function <code>dfx</code>, that depends only on one
variable:</p>
<pre class="ruby"><span class="ruby-identifier">puts</span> <span class="ruby-node">"Arguments: #{dfx.args}"</span>
</pre>
<p>We can write a Newton method. The solution is found iteratively solving the
recursive equation:</p>
<pre>x[k + 1] = x[k] - ( f(x[k]) / f'(x[k]) )</pre>
<p>Let's write an algorithm that takes the symblic expression, and creates
its own method (e.g.: using <code>Proc</code> objects). Here an example
with our function:</p>
<pre class="ruby"><span class="ruby-identifier">unused</span> = (<span class="ruby-identifier">dfx</span><span class="ruby-operator">/</span><span class="ruby-identifier">dfx</span>.<span class="ruby-identifier">diff</span>(<span class="ruby-identifier">x</span>)).<span class="ruby-identifier">simplify</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"unused(x) = #{unused}"</span>
<span class="ruby-comment"># => unused(x) = ((((1 - x) * 2) * -1)) / (((-1 * 2) * -1))</span>
<span class="ruby-identifier">unused_proc</span> = <span class="ruby-identifier">unused</span>.<span class="ruby-identifier">as_proc</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"unused(12.0) = #{unused.call({"x" => 12.0})}"</span>
<span class="ruby-comment"># => unused(12.0) = 11.0</span>
</pre>
<p>First of all, let's write a function that contains the algorithm. We
want to give as input a symbolic function of one variable, it must reply
with the value of the variable in which the function as value equal to
zero:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier">newton</span>(<span class="ruby-identifier">f</span>, <span class="ruby-identifier">init</span>=<span class="ruby-value">3.0</span>, <span class="ruby-identifier">tol</span>=<span class="ruby-value">1E-8</span>, <span class="ruby-identifier">kmax</span>=<span class="ruby-value">100</span>)
<span class="ruby-identifier">k</span> = <span class="ruby-value">0</span>
<span class="ruby-identifier">x</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>]
<span class="ruby-identifier">s</span> = {<span class="ruby-identifier">x</span>.<span class="ruby-identifier">name</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">init</span>} <span class="ruby-comment"># <-This is the solution dictionary</span>
<span class="ruby-identifier">fp</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">as_proc</span> <span class="ruby-comment"># <- This is a parsed object</span>
<span class="ruby-identifier">df</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">diff</span>(<span class="ruby-identifier">x</span>).<span class="ruby-identifier">simplify</span> <span class="ruby-comment"># <- This is still symbolic</span>
<span class="ruby-identifier">res</span> = (<span class="ruby-identifier">f</span><span class="ruby-operator">/</span><span class="ruby-identifier">df</span>).<span class="ruby-identifier">as_proc</span> <span class="ruby-comment"># <- This is a parsed object</span>
<span class="ruby-identifier">f0</span> = <span class="ruby-identifier">fp</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">s</span>)
<span class="ruby-identifier">k</span> = <span class="ruby-value">0</span>
<span class="ruby-identifier">loop</span> <span class="ruby-keyword">do</span>
<span class="ruby-comment"># Algorithm</span>
<span class="ruby-identifier">s</span>[<span class="ruby-identifier">x</span>.<span class="ruby-identifier">name</span>] = <span class="ruby-identifier">s</span>[<span class="ruby-identifier">x</span>.<span class="ruby-identifier">name</span>] <span class="ruby-operator">-</span> <span class="ruby-identifier">res</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">s</span>)
<span class="ruby-comment"># Tolerance check</span>
<span class="ruby-identifier">f1</span> = <span class="ruby-identifier">fp</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">s</span>)
<span class="ruby-keyword">if</span> (<span class="ruby-identifier">f1</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">f0</span>).<span class="ruby-identifier">abs</span> <span class="ruby-operator"><</span> <span class="ruby-identifier">tol</span>
<span class="ruby-keyword">break</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">f0</span> = <span class="ruby-identifier">f1</span>
<span class="ruby-keyword">end</span>
<span class="ruby-comment"># Iterations check</span>
<span class="ruby-identifier">k</span> = <span class="ruby-identifier">k</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">break</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">k</span> <span class="ruby-operator">></span> <span class="ruby-identifier">kmax</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"Solution after #{k} iterations: #{x} = #{s[x.name]}, f(#{x}) = #{f0}"</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">s</span>[<span class="ruby-identifier">x</span>.<span class="ruby-identifier">name</span>]
<span class="ruby-keyword">end</span>
</pre>
<p><strong>Transforming the symbolic function into a <code>Proc</code> makes
the code more efficient. It is not mandatory, but higlhy suggested in case
of iterative algorithms</strong>.</p>
<p>Let's call our new function, using as argument the derivative of the
function that we want to optimize:</p>
<pre class="ruby"><span class="ruby-identifier">x_opt</span> = <span class="ruby-identifier">newton</span>(<span class="ruby-identifier">dfx</span>)
<span class="ruby-comment"># => Solution after 1 iterations: x = 1.0, f(x) = -0.0</span>
</pre>
<p>We can use the solution of <code>x</code>, to get the value of
<code>y</code>:</p>
<pre class="ruby"><span class="ruby-identifier">puts</span> <span class="ruby-node">"Optimum in #{x} = #{x_opt} and #{y} = #{g.call({x => x_opt})}"</span>
<span class="ruby-comment"># => Optimum in x = 1.0 and y = 1.0</span>
</pre>
<h2 id="label-Disclaimer">Disclaimer<span><a href="#label-Disclaimer">¶</a> <a href="#top">↑</a></span></h2>
<p>This is a work in progress and mainly a proof of concept. What really is
missing is a ~~graph~~ a way to perform better simplifications.</p>
<h2 id="label-Full+example+code">Full example code<span><a href="#label-Full+example+code">¶</a> <a href="#top">↑</a></span></h2>
<pre class="ruby"><span class="ruby-identifier">require</span> <span class="ruby-string">'Mr.CAS'</span>
<span class="ruby-comment"># Define the function</span>
<span class="ruby-identifier">x</span>, <span class="ruby-identifier">y</span> = <span class="ruby-constant">CAS</span><span class="ruby-operator">::</span><span class="ruby-identifier">vars</span> <span class="ruby-string">"x"</span>, <span class="ruby-string">"y"</span>
<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span> = <span class="ruby-constant">CAS</span><span class="ruby-operator">::</span><span class="ruby-identifier">const</span> <span class="ruby-value">1.0</span>, <span class="ruby-value">100.0</span>
<span class="ruby-identifier">f</span> = ((<span class="ruby-identifier">a</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">x</span>) <span class="ruby-operator">**</span> <span class="ruby-value">2</span>) <span class="ruby-operator">+</span> <span class="ruby-identifier">b</span> <span class="ruby-operator">*</span> ((<span class="ruby-identifier">y</span> <span class="ruby-operator">-</span> (<span class="ruby-identifier">x</span> <span class="ruby-operator">**</span> <span class="ruby-value">2</span>)) <span class="ruby-operator">**</span> <span class="ruby-value">2</span>)
<span class="ruby-identifier">puts</span> <span class="ruby-node">"f = #{f}"</span>
<span class="ruby-comment"># Derivate wrt variables</span>
<span class="ruby-identifier">dfx</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">diff</span>(<span class="ruby-identifier">x</span>).<span class="ruby-identifier">simplify</span>
<span class="ruby-identifier">dfy</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">diff</span>(<span class="ruby-identifier">y</span>).<span class="ruby-identifier">simplify</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"df/dx = #{dfx}"</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"df/dy = #{dfy}"</span>
<span class="ruby-comment"># Perform substitutions</span>
<span class="ruby-identifier">g</span> = (<span class="ruby-identifier">x</span> <span class="ruby-operator">**</span> <span class="ruby-value">2</span>)
<span class="ruby-identifier">dfx</span> = <span class="ruby-identifier">dfx</span>.<span class="ruby-identifier">subs</span>({<span class="ruby-identifier">y</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">g</span>}).<span class="ruby-identifier">simplify</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"df/dx = #{dfx}"</span>
<span class="ruby-comment"># Arguments of a function</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"Arguments: #{dfx.args}"</span>
<span class="ruby-comment"># Metaprogramming: Create a Proc from symbolic math</span>
<span class="ruby-identifier">unused</span> = (<span class="ruby-identifier">dfx</span><span class="ruby-operator">/</span><span class="ruby-identifier">dfx</span>.<span class="ruby-identifier">diff</span>(<span class="ruby-identifier">x</span>)).<span class="ruby-identifier">simplify</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"unused(x) = #{unused}"</span>
<span class="ruby-identifier">unused_proc</span> = <span class="ruby-identifier">unused</span>.<span class="ruby-identifier">as_proc</span>
<span class="ruby-comment"># Testing the Proc. The feed must have string as key to identify</span>
<span class="ruby-comment"># the variable</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"unused(12.0) = #{unused.call({"x" => 12.0})}"</span>
<span class="ruby-comment"># We will not use this function, instead we will let the</span>
<span class="ruby-comment"># algorithm to create its own</span>
<span class="ruby-comment"># Newton algorthm on the fly, that creates its own formula!</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">newton</span>(<span class="ruby-identifier">f</span>, <span class="ruby-identifier">init</span>=<span class="ruby-value">3.0</span>, <span class="ruby-identifier">tol</span>=<span class="ruby-value">1E-8</span>, <span class="ruby-identifier">kmax</span>=<span class="ruby-value">100</span>)
<span class="ruby-identifier">k</span> = <span class="ruby-value">0</span>
<span class="ruby-identifier">x</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>]
<span class="ruby-identifier">s</span> = {<span class="ruby-identifier">x</span>.<span class="ruby-identifier">name</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">init</span>} <span class="ruby-comment"># <-This is the solution dictionary</span>
<span class="ruby-identifier">fp</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">as_proc</span> <span class="ruby-comment"># <- This is a parsed object</span>
<span class="ruby-identifier">df</span> = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">diff</span>(<span class="ruby-identifier">x</span>).<span class="ruby-identifier">simplify</span> <span class="ruby-comment"># <- This is still symbolic</span>
<span class="ruby-identifier">res</span> = (<span class="ruby-identifier">f</span><span class="ruby-operator">/</span><span class="ruby-identifier">df</span>).<span class="ruby-identifier">as_proc</span> <span class="ruby-comment"># <- This is a parsed object</span>
<span class="ruby-identifier">f0</span> = <span class="ruby-identifier">fp</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">s</span>)
<span class="ruby-identifier">k</span> = <span class="ruby-value">0</span>
<span class="ruby-identifier">loop</span> <span class="ruby-keyword">do</span>
<span class="ruby-comment"># Algorithm</span>
<span class="ruby-identifier">s</span>[<span class="ruby-identifier">x</span>.<span class="ruby-identifier">name</span>] = <span class="ruby-identifier">s</span>[<span class="ruby-identifier">x</span>.<span class="ruby-identifier">name</span>] <span class="ruby-operator">-</span> <span class="ruby-identifier">res</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">s</span>)
<span class="ruby-comment"># Tolerance check</span>
<span class="ruby-identifier">f1</span> = <span class="ruby-identifier">fp</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">s</span>)
<span class="ruby-keyword">if</span> (<span class="ruby-identifier">f1</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">f0</span>).<span class="ruby-identifier">abs</span> <span class="ruby-operator"><</span> <span class="ruby-identifier">tol</span>
<span class="ruby-keyword">break</span>
<span class="ruby-keyword">else</span>
<span class="ruby-identifier">f0</span> = <span class="ruby-identifier">f1</span>
<span class="ruby-keyword">end</span>
<span class="ruby-comment"># Iterations check</span>
<span class="ruby-identifier">k</span> = <span class="ruby-identifier">k</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">break</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">k</span> <span class="ruby-operator">></span> <span class="ruby-identifier">kmax</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"Solution after #{k} iterations: #{x} = #{s[x.name]}, f(#{x}) = #{f0}"</span>
<span class="ruby-keyword">return</span> <span class="ruby-identifier">s</span>[<span class="ruby-identifier">x</span>.<span class="ruby-identifier">name</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-comment"># Let's call our shining algorithm:</span>
<span class="ruby-identifier">x_opt</span> = <span class="ruby-identifier">newton</span>(<span class="ruby-identifier">dfx</span>)
<span class="ruby-comment"># Let's see the final result for both:</span>
<span class="ruby-identifier">puts</span> <span class="ruby-node">"Optimum in #{x} = #{x_opt} and #{y} = #{g.call({x => x_opt})}"</span>
</pre>
<h2 id="label-To+do">To do<span><a href="#label-To+do">¶</a> <a href="#top">↑</a></span></h2>
<h4 id="label-Simple">Simple<span><a href="#label-Simple">¶</a> <a href="#top">↑</a></span></h4>
<ul><li>
<p>[ ] substitute <code>CAS::Invert</code> with <code>CAS::Neg</code></p>
</li><li>
<p>[ ] substitute <code>CAS::Condition</code> with
<code>CAS::Expression</code></p>
</li><li>
<p>[x] move code generation to external plugins that can be loaded on demand</p>
</li><li>
<p>[x] <code>CAS::Sum</code> and <code>CAS::Prod</code> inherits from
<code>CAS::NaryOp</code> instead of <code>CAS::BinaryOp</code></p>
</li></ul>
<h4 id="label-Complex">Complex<span><a href="#label-Complex">¶</a> <a href="#top">↑</a></span></h4>
<ul><li>
<p>[ ] implement <code>CAS::VectorVariable</code> and
<code>CAS::MatrixVariable</code></p>
</li><li>
<p>[ ] Replace <code>CAS::Op</code> and <code>CAS::BinaryOp</code> with a
single <code>CAS::Op</code> equal to <code>CAS::NaryOp</code></p>
</li></ul>
<h5 id="label-Extremely+complex">Extremely complex<span><a href="#label-Extremely+complex">¶</a> <a href="#top">↑</a></span></h5>
<ul><li>
<p>[ ] Implement the Risch algorithms for symbolic integrations</p>
</li></ul>
</main>
<footer id="validator-badges" role="contentinfo">
<p><a href="http://validator.w3.org/check/referer">Validate</a>
<p>Generated by <a href="http://docs.seattlerb.org/rdoc/">RDoc</a> 4.2.1.
<p>Based on <a href="http://deveiate.org/projects/Darkfish-RDoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
</footer>