<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[SciRuby]]></title>
  <link href="http://sciruby.com/atom.xml" rel="self"/>
  <link href="http://sciruby.com/"/>
  <updated>2021-02-21T12:50:48+05:30</updated>
  <id>http://sciruby.com/</id>
  <author>
    <name><![CDATA[SciRuby]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Tensors using NumRuby]]></title>
    <link href="http://sciruby.com/blog/2021/02/16/tensors/"/>
    <updated>2021-02-16T21:49:00+05:30</updated>
    <id>http://sciruby.com/blog/2021/02/16/tensors</id>
    <content type="html"><![CDATA[<p>Tensor word can have slightly different meaning depending upon the nature of study, like it&#8217;s defined differently in Physics, slightly different in computer science. In computer terms, it is basically a n-dimensional array. A scalar (one value) is a tensor with 0 dimensions, a vector is a tensor with 1 dimension, a matrix is a tensor with 2 dimensions.</p>

<p>It&#8217;s possible to define a tensor in Ruby using the <code>Array</code> class of Ruby but it gets tedious when defining multi-dimensional tensors. Also, the <code>Array</code> object is designed to be heterogeneous which means that the elements of the array can be of different type or different classes which would seem as a plus point overall but it has a huge downside. Due to <code>Array</code> being heterogeneous, the memory allocation has to be in such a way that any element of any size can be added or removed from the array, which causes a lot of re-allocations. Also, the indexing and other array functions gets slower due to the heterogeneous nature.</p>

<p>What if there&#8217;s a scenario where there is only one type of tensor elements, which means that a homogeneous array would also do, and there are memory and speed constraints? <code>NumRuby</code> is the solution for such requirements.</p>

<h2>Tensors in NumRuby</h2>

<p>A tensor can be defined using the <code>NMatrix</code> object of <code>NumRuby</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">N</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="n">shape</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="n">elements</span><span class="o">]</span><span class="p">,</span> <span class="ss">:type</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>shape</code> is the number of dimensions and size of each dimension of the tensor. For example, <code>[2, 2, 2]</code> shape tensor is a tensor with 3 dimensions and each dimension of size 2, hence number of elements is 8. A sample value of elements array for this could be <code>[1, 2, 3, 4, 5, 6, 7, 8]</code>. <code>type</code> is the data type of each of the tensor element, it could be any of <code>:nm_bool</code>, <code>:nm_int</code>, <code>:nm_float32</code>, <code>:nm_float64</code>, <code>:nm_complex32</code> or <code>:nm_complex64</code> depending on the requirements.</p>

<p>An example usage is shown below:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="o">]</span><span class="p">,</span> <span class="ss">:nm_int</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">2</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">.</span><span class="n">elements</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">3</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">.</span><span class="n">shape</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">4</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">1</span>
</span><span class='line'><span class="o">[</span><span class="mi">5</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">3</span>
</span><span class='line'><span class="o">[</span><span class="mi">6</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">.</span><span class="n">dtype</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="ss">:nm_int</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Elementwise Operations</h2>

<p>One can also perform elementwise operations using <code>NumRuby</code>. Elementwise operations are broadly of 2 types, Uni-operand and bi-operand.</p>

<h3>Uni-Operand Operations</h3>

<p>Uni-operand operators are those that apply to just one tensor. For example, sine, cos or tan of each of element of the tensor.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="o">]</span><span class="p">,</span> <span class="ss">:nm_float64</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">1</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">2</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">.</span><span class="n">sin</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="mi">8414709848078965</span><span class="p">,</span>  <span class="mi">0</span><span class="o">.</span><span class="mi">9092974268256817</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="mi">1411200080598672</span><span class="p">,</span> <span class="o">-</span><span class="mi">0</span><span class="o">.</span><span class="mi">7568024953079282</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">3</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">.</span><span class="n">cos</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span> <span class="mi">0</span><span class="o">.</span><span class="mi">5403023058681398</span><span class="p">,</span> <span class="o">-</span><span class="mi">0</span><span class="o">.</span><span class="mi">4161468365471424</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[-</span><span class="mi">0</span><span class="o">.</span><span class="mi">9899924966004454</span><span class="p">,</span> <span class="o">-</span><span class="mi">0</span><span class="o">.</span><span class="mi">6536436208636119</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Bi-Operand Operations</h3>

<p>Bi-operand operators are those that apply to two tensor. For example, addition, subtraction or multiplication of each of the corresponding elements of the the 2 tensor.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="o">]</span><span class="p">,</span> <span class="ss">:nm_float64</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">1</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">2</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">M</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">,</span> <span class="ss">:nm_float64</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">3</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">+</span><span class="n">M</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">6</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">7</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">4</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">*</span><span class="n">M</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span>  <span class="mi">4</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">9</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">12</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Linear Algebra</h2>

<p><code>NumRuby</code> also supports linear algebra capabilities for 2-dimensional tensors. One can easily do operations such as matrix inverse, dot product, matrix decompositions.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="o">]</span><span class="p">,</span> <span class="ss">:nm_float64</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">1</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">2</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">M</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span><span class="p">,</span> <span class="ss">:nm_float64</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span><span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">3</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">M</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[</span> <span class="mi">8</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span>  <span class="mi">8</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span><span class="mi">18</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">18</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">4</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">.</span><span class="n">invert</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'> <span class="o">[-</span><span class="mi">1</span><span class="o">.</span><span class="mi">9999999999999996</span><span class="p">,</span>  <span class="mi">0</span><span class="o">.</span><span class="mi">9999999999999998</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="o">[</span> <span class="mi">1</span><span class="o">.</span><span class="mi">4999999999999998</span><span class="p">,</span> <span class="o">-</span><span class="mi">0</span><span class="o">.</span><span class="mi">4999999999999999</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="o">[</span><span class="mi">5</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">N</span><span class="o">.</span><span class="n">det</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">-</span><span class="mi">2</span><span class="o">.</span><span class="mi">0</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2019 : Adding ImageMagick backend, IRuby support and additional functionalities to Rubyplot]]></title>
    <link href="http://sciruby.com/blog/2019/08/29/gsoc-2019-rubyplot/"/>
    <updated>2019-08-29T02:24:00+05:30</updated>
    <id>http://sciruby.com/blog/2019/08/29/gsoc-2019-rubyplot</id>
    <content type="html"><![CDATA[<p><strong>Table of Contents</strong>
* TOC
{:toc}</p>

<h1>Introduction</h1>

<p>With GSoC 2019 coming to an end, this is my final blog which mentions all my work for the project Rubyplot.</p>

<h1>What is Rubyplot?</h1>

<p>RubyPlot is a plotting library in Ruby for scientific development inspired by the library Matplotlib for Python. Users can create various types of plots like scatter plot, bar plot, etc. and can also create subplots which combine various of these plots. The long-term goal of the library is to build an efficient, scalable and user-friendly library with a backend-agnostic frontend to support various backends so that the library can be used on any device.</p>

<h2>Examples</h2>

<p>Creating graphs in Rubyplot is very simple and can be done in just a few lines of code, for example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;rubyplot&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">figure</span> <span class="o">=</span> <span class="no">Rubyplot</span><span class="o">::</span><span class="no">Figure</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">width</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span> <span class="ss">height</span><span class="p">:</span> <span class="mi">30</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">axes00</span> <span class="o">=</span> <span class="n">figure</span><span class="o">.</span><span class="n">add_subplot!</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">plot!</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
</span><span class='line'>  <span class="n">d</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="mi">360</span><span class="p">)</span><span class="o">.</span><span class="n">step</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="o">.</span><span class="n">to_a</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">data</span> <span class="n">d</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="no">Math</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">a</span> <span class="o">*</span> <span class="no">Math</span><span class="o">::</span><span class="no">PI</span> <span class="o">/</span> <span class="mi">180</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">fmt</span> <span class="o">=</span> <span class="s1">&#39;ok-&#39;</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">marker_fill_color</span> <span class="o">=</span> <span class="ss">:white</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">marker_size</span> <span class="o">=</span> <span class="mi">0</span><span class="o">.</span><span class="mi">5</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">line_width</span> <span class="o">=</span> <span class="mi">2</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;sine&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="s2">&quot;A plot function example&quot;</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">square_axes</span> <span class="o">=</span> <span class="kp">false</span>
</span><span class='line'>
</span><span class='line'><span class="n">figure</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;example1.png&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Has the output:<br/>
<img src="https://raw.githubusercontent.com/alishdipani/alishdipani.github.io/master/_posts/Resources/Wrapping_up_GSoC_2019/example1.png" alt="Example1" /></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;rubyplot&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">figure</span> <span class="o">=</span> <span class="no">Rubyplot</span><span class="o">::</span><span class="no">Figure</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">width</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span> <span class="ss">height</span><span class="p">:</span> <span class="mi">30</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">axes00</span> <span class="o">=</span> <span class="n">figure</span><span class="o">.</span><span class="n">add_subplot!</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">candle_stick!</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">lows</span> <span class="o">=</span> <span class="o">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">10</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">highs</span> <span class="o">=</span> <span class="o">[</span><span class="mi">40</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">50</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">opens</span> <span class="o">=</span> <span class="o">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">20</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">closes</span> <span class="o">=</span> <span class="o">[</span><span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">40</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">color</span> <span class="o">=</span> <span class="ss">:yellow</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">candle_stick!</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">lows</span> <span class="o">=</span> <span class="o">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">highs</span> <span class="o">=</span> <span class="o">[</span><span class="mi">50</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">65</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">60</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">opens</span> <span class="o">=</span> <span class="o">[</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">20</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">closes</span> <span class="o">=</span> <span class="o">[</span><span class="mi">35</span><span class="p">,</span> <span class="mi">35</span><span class="p">,</span> <span class="mi">45</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">75</span><span class="p">,</span> <span class="mi">50</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">color</span> <span class="o">=</span> <span class="ss">:blue</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="s2">&quot;A multi candle-stick plot&quot;</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">square_axes</span> <span class="o">=</span> <span class="kp">false</span>
</span><span class='line'>
</span><span class='line'><span class="n">figure</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;example2.png&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Has the output:<br/>
<img src="https://raw.githubusercontent.com/alishdipani/alishdipani.github.io/master/_posts/Resources/Wrapping_up_GSoC_2019/example2.png" alt="Example2" /></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;rubyplot&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">figure</span> <span class="o">=</span> <span class="no">Rubyplot</span><span class="o">::</span><span class="no">Figure</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">width</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span> <span class="ss">height</span><span class="p">:</span> <span class="mi">30</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">axes00</span> <span class="o">=</span> <span class="n">figure</span><span class="o">.</span><span class="n">add_subplot!</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">bar!</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">data</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">color</span> <span class="o">=</span> <span class="ss">:lemon</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">spacing_ratio</span> <span class="o">=</span> <span class="mi">0</span><span class="o">.</span><span class="mi">2</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">bar!</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">data</span> <span class="o">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">color</span> <span class="o">=</span> <span class="ss">:blue</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">bar!</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">data</span> <span class="o">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">color</span> <span class="o">=</span> <span class="ss">:red</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="s2">&quot;A multi bar plot&quot;</span>
</span><span class='line'><span class="n">axes00</span><span class="o">.</span><span class="n">square_axes</span> <span class="o">=</span> <span class="kp">false</span>
</span><span class='line'>
</span><span class='line'><span class="n">figure</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;example3.png&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Has the output:<br/>
<img src="https://raw.githubusercontent.com/alishdipani/alishdipani.github.io/master/_posts/Resources/Wrapping_up_GSoC_2019/example3.png" alt="Example3" /></p>

<h1>History of Rubyplot</h1>

<p>Rubyplot started as two GSoC 2018 projects by Pranav Garg<a href="https://github.com/pgtgrly">(@pgtgrly)</a> and Arafat Dad Khan<a href="https://github.com/Arafatk">(@Arafatk)</a> and the mentors from The Ruby Science Foundation<a href="http://sciruby.com/">(SciRuby)</a>, Sameer Deshmukh<a href="https://github.com/v0dro">(@v0dro)</a>, John Woods<a href="https://github.com/mohawkjohn">(@mohawkjohn)</a> and Pjotr Prins<a href="https://github.com/pjotrp">(@pjotrp)</a>. Pranav Garg worked on the GRRuby which had the GR backend and Arafat Dad Khan worked on Ruby Matplotlib which had the ImageMagick backend. The ultimate goal of combining both and creating Rubyplot. After GSoC 2018, Sameer Deshmukh combined both projects and created Rubyplot and he has maintained it ever since. Around May 2019, I started working on Rubyplot as a part of GSoC 2019.</p>

<h1>GSoC 2019</h1>

<p>As a part of GSoC 2019, my project had 3 major deliverables:
1. <strong>ImageMagick support</strong>(Phase 1): Support for ImageMagick back-end will be added in addition to the currently supported back-end GR, the front-end of the library will be back-end agnostic and the current overall integrity of the library will be preserved.<br/>
2. <strong>Plotting and show function</strong>(Phase 2): A new plot function will be added which plots markers (for example circles) to form a scatter plot with the points as inputs (same as plot function in Matplotlib). A new function show will be added which will allow viewing of a plot without saving it. This plot function will be back-end agnostic and hence will support both GR and Magick back-end.<br/>
3. <strong>Integration with iruby notebooks</strong>(Phase 3): Rubyplot will be integrated with iruby notebooks supporting all backends and allowing inline plotting.</p>

<p>As a part of GSoC 2019, I completed all the deliverables I had initially planned along with a tutorial for the library and some other general improvements.<br/>
Details of my work are as follows:</p>

<h2>Phase 1</h2>

<p>During Phase 1, I focused on setting up the ImageMagick backend which involved the basic functionality required for any backend of the library which are X-axis and Y-axis transform functions, <code>within_window</code> function which is responsible for placing the plots in the correct position, function for drawing the X and Y axis, functions for drawing the text and scaling the figure according to the dimensions given by the user. I implemented these functions using internal rmagick functions which were very useful like <code>scale</code>, <code>translate</code>, <code>rotate</code>, etc.<br/>
After this, I worked on the scatter plot, which was the first plot I ever worked on. This plot had a very particular and interesting problem, which was that different types of markers were internally implemented in the GR backend, but for ImageMagick backend, I had to implement everything using basic shapes like circles, lines, polygons and rectangles. To solve this I created a hash of lambdas which had the code to create different types of markers using the basic shapes.<br/>
After this I implemented all the simple plots which Rubyplot supports, these are line plot, area plot, bar plot, histogram, box plot, bubble plot, candle-stick plot and error-bar plot.</p>

<p>So, during Phase 1, I completed the following deliverables -<br/>
1. Set up the ImageMagick backend to have the basic functionality.<br/>
2. Implemented and tested the simple plots in Rubyplot which are scatter plot, line plot, area plot, bar plot, histogram, box plot, bubble plot, candle-stick plot and error-bar plot.</p>

<p>Code for Phase 1 can be found <a href="https://github.com/SciRuby/rubyplot/pull/45/files/01a26777175c83e3e44a33d5ac5d6544b8ff9353..95f24730e04eb13460ed088dcf7569848b66a2ea">here</a>.</p>

<h2>Phase 2</h2>

<p>I started Phase 2 by implementing the multi plots which are multi stack-bar plot, multi-bar plot, multi-box plot and multi candle-stick plot.<br/>
Next, I implemented the <code>plot</code> function which is a combination of scatter plot and line plot, using the plot function the user can easily create a scatter plot or a line plot or a combination of both. The most interesting feature of the <code>plot</code> function is the <code>fmt</code> argument which sets the marker type, line type and the colour of the plot using just characters, so instead of writing the name of the type and setting the variables, the user can simply input a string in <code>fmt</code> argument which has the characters for corresponding marker type, line type and colour.<br/>
Next was to implement the <code>show</code> function which is an alternative to <code>write</code> function. It draws the Figure and shows it on a temporary pop-up window without the need of saving the Figure on the device, this allows the user to test the code quickly and easily. This was done by using internal functions of the backends which are <code>display</code> for ImageMagick and <code>gr_updatews</code> for GR.</p>

<p>So, during Phase 2, I completed the following deliverables -<br/>
1. Implemented and tested the multi plots in Rubyplot which are multi stack-bar plot, multi-bar plot, multi-box plot and multi candle-stick plot.<br/>
2. Implemented and tested the <code>plot</code> function with fmt argument.<br/>
3. Implemented and tested the <code>show</code> function.</p>

<p>Code for Phase 2 can be found <a href="https://github.com/SciRuby/rubyplot/pull/45/files/36497cc3fdb6b9eddaee51777509d1f388a8ba4a..f918e9c9f390cfa96e453f3db610eeaa8f3acbed">here</a> and <a href="https://github.com/SciRuby/rubyplot/pull/52/files/21d2450229ce8508f8a906914fd4bf47e1c62fa3..5947c911d290f34a09effca5ce3e866519b8c5db">here</a>.</p>

<h2>Phase 3</h2>

<p>During Phase 3, I integrated Rubyplot with the IRuby notebooks which allow the user to draw figures inside the notebook just by using the <code>show</code> function, through this integration the user can quickly and easily test the code step by step before running the whole codebase.<br/>
I also implemented ticks for ImageMagick backend.<br/>
Finally, I created a tutorial for the library which also contains template codes for all the plots which a user can easily get familiar with the working of the library and start using it.</p>

<p>So, during Phase 3, I completed the following deliverables -<br/>
1. Integrated Rubyplot with IRuby notebooks with the support for inline plotting.<br/>
2. Implemented and tested ticks for Magick backend.<br/>
3. Created the tutorial for Rubyplot.</p>

<p>Code for Phase 3 can be found <a href="https://github.com/SciRuby/rubyplot/pull/52/files/ca2aa7397581eaf92b64522361e3565f032e6250..3624962d8f96e3611c6bbc55a5c2c8aa1a299e27">here</a>.</p>

<h1>Resources(blogs, code, etc.)</h1>

<h2>Previous Work</h2>

<ul>
<li>GSoC 2018 project GRRuby by Pranav Garg can be found <a href="https://github.com/pgtgrly/GRruby-extension">here</a></li>
<li>GSoC 2018 project Ruby Matplotlib by Arafat Dad Khan can be found <a href="https://github.com/Arafatk/magick-rubyplot">here</a></li>
<li>A talk on Rubyplot by Pranav Garg in RubyConf 2018 can be found <a href="https://youtu.be/7QBkckZ1aNQ">here</a></li>
</ul>


<h2>My work</h2>

<ul>
<li>Daily updates can be found <a href="https://discourse.ruby-data.org/t/gsoc-2019-project-rubyplot-discussion/57">here</a></li>
<li>Proposal can be found <a href="https://github.com/alishdipani/rubyplot/wiki/GSoC-2019-Proposal">here</a></li>
<li>Tutorial notebook can be found <a href="https://github.com/alishdipani/rubyplot/blob/master/tutorial/magick/Rubyplot_Tutorial(Magick">here</a>.ipynb) and can be viewed online(rendered) <a href="https://nbviewer.jupyter.org/github/alishdipani/rubyplot/blob/master/tutorial/magick/Rubyplot_Tutorial%28Magick%29.ipynb">here</a></li>
<li>Rubyplot Github Repository can be found <a href="https://github.com/SciRuby/rubyplot">here</a></li>
<li>All my work can be found in these PRs: <a href="https://github.com/SciRuby/rubyplot/pull/45">PR#45</a> and <a href="https://github.com/SciRuby/rubyplot/pull/52">PR#52</a></li>
<li>Other blogs can be found here:

<ol>
<li><a href="https://alishdipani.github.io/gsoc2019/2019/06/08/GSoC-2019-project-introduction/">GSoC 2019 project introduction</a></li>
<li><a href="https://alishdipani.github.io/gsoc2019/2019/06/09/Rubyplot-installation-guide/">Rubyplot installation guide</a></li>
<li><a href="https://alishdipani.github.io/gsoc2019/2019/06/10/The-Scatter-plot-example/">The Scatter plot example</a></li>
<li><a href="https://alishdipani.github.io/gsoc2019/2019/06/28/Simple-Plots-in-Rubyplot/">Simple Plots in Rubyplot</a></li>
<li><a href="https://alishdipani.github.io/gsoc2019/2019/07/13/Multi-plots-in-Rubyplot/">Multi plots in Rubyplot</a></li>
<li><a href="https://alishdipani.github.io/gsoc2019/2019/07/26/The-show-and-the-plot-functions/">The show and the plot functions</a></li>
<li><a href="https://alishdipani.github.io/gsoc2019/2019/08/22/IRuby-integration-and-ticks/">IRuby integration and ticks</a></li>
</ol>
</li>
</ul>


<h1>Future Work</h1>

<p>I plan to keep contributing to Rubyplot and also start contributing to other projects of SciRuby.<br/>
Future work to be done for Rubyplot is to write documentation, add more tests, add more types of plots, add more backends, make the plots interactive and in future add the feature for plotting 3-Dimensional graphs which would also be interactive.</p>

<h1>EndNote</h1>

<p>With this, we come to an end of GSoC 2019. These 3 months have been very challenging, interesting, exciting and fun. I got to learn a lot of things while working on Rubyplot and while interacting with my mentors. I have experienced an improvement in my Software development skills and programming in general which will help me a lot in future. I would love to keep working with SciRuby on more such interesting projects and maybe even try for GSoC again next year ;)</p>

<h1>Acknowledgements</h1>

<p>I would like to express my gratitude to my mentor Sameer Deshmukh for his guidance and support. He was always available and had solutions to every problem I faced, I got to learn a lot from him and I hope to learn a lot more from him in the future. I could not have asked for a better mentor.</p>

<p>I would also like to thank Pranav Garg who introduced me to Ruby and also to the SciRuby community. During his GSoC 2018 project, he introduced me to the Rubyplot library and helped me get started with it. His suggestions were very helpful during my GSoC 2019 project.</p>

<p>I would also like to thank mentors from SciRuby Prasun Anand and Shekhar Prasad Rajak for mentoring me and organising the occasional meetings and code reviews. I would also like to thank Udit Gulati for his helpful insights during the code reviews.</p>

<p>I am grateful to Google and the Ruby Science Foundation for this golden opportunity.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2019: Adding features to NMatrix core]]></title>
    <link href="http://sciruby.com/blog/2019/08/26/gsoc-2019-adding-features-to-nmatrix-core/"/>
    <updated>2019-08-26T23:49:00+05:30</updated>
    <id>http://sciruby.com/blog/2019/08/26/gsoc-2019-adding-features-to-nmatrix-core</id>
    <content type="html"><![CDATA[<p>The GSoC coding period has come to an end. It&#8217;s been quite a learning experience for me and has given me an opportunity to come out of my comfort zone and explore new things. I feel quite delighted knowing that I have contributed a significant amount to the project. This post summarizes my work on <a href="https://github.com/sciruby/numruby">NumRuby</a> during the GSoC period.</p>

<p>GSoC 2019 proposal - <a href="https://docs.google.com/document/d/1MR01QZeX_8h7a16nmkOYlyrVt--osB1Yg9Vo0xXYtSw/edit?usp=sharing">https://docs.google.com/document/d/1MR01QZeX_8h7a16nmkOYlyrVt&#8211;osB1Yg9Vo0xXYtSw/edit?usp=sharing</a></p>

<h2>Pull requests</h2>

<ul>
<li>Indexing, iterating, slicing - <a href="https://github.com/SciRuby/numruby/pull/19">https://github.com/SciRuby/numruby/pull/19</a></li>
<li>Fix compiler warnings - <a href="https://github.com/SciRuby/numruby/pull/21">https://github.com/SciRuby/numruby/pull/21</a></li>
<li>Dimensional iterators - <a href="https://github.com/SciRuby/numruby/pull/22">https://github.com/SciRuby/numruby/pull/22</a></li>
<li>Broadcasting - <a href="https://github.com/SciRuby/numruby/pull/23">https://github.com/SciRuby/numruby/pull/23</a></li>
<li>Lapack wrappers - <a href="https://github.com/SciRuby/numruby/pull/26">https://github.com/SciRuby/numruby/pull/26</a></li>
<li>NumRuby::Linalg - <a href="https://github.com/SciRuby/numruby/pull/30">https://github.com/SciRuby/numruby/pull/30</a></li>
</ul>


<h2>Blog Posts</h2>

<ul>
<li>GSoC project introduction - <a href="https://uditgulati.github.io/blog/open-source/2019/05/21/gsoc-project-introduction-nmatrix.html">https://uditgulati.github.io/blog/open-source/2019/05/21/gsoc-project-introduction-nmatrix.html</a></li>
<li>GSoC weeks 1, 2 - <a href="https://uditgulati.github.io/blog/open-source/2019/06/10/gsoc-week-1-2.html">https://uditgulati.github.io/blog/open-source/2019/06/10/gsoc-week-1-2.html</a></li>
<li>GSoC weeks 3, 4 - <a href="https://uditgulati.github.io/blog/open-source/2019/06/26/gsoc-week-3-4.html">https://uditgulati.github.io/blog/open-source/2019/06/26/gsoc-week-3-4.html</a></li>
<li>GSoC weeks 5, 6 - <a href="https://uditgulati.github.io/blog/open-source/2019/07/10/gsoc-week-5-6.html">https://uditgulati.github.io/blog/open-source/2019/07/10/gsoc-week-5-6.html</a></li>
<li>GSoC weeks 7, 8 - <a href="https://uditgulati.github.io/blog/open-source/2019/07/25/gsoc-week-7-8.html">https://uditgulati.github.io/blog/open-source/2019/07/25/gsoc-week-7-8.html</a></li>
<li>GSoC weeks 9, 10 - <a href="https://uditgulati.github.io/blog/open-source/2019/08/16/gsoc-week-9-10.html">https://uditgulati.github.io/blog/open-source/2019/08/16/gsoc-week-9-10.html</a></li>
</ul>


<h2>Future work</h2>

<ul>
<li>As these features are core to NMatrix, they need to be tested more tightly and benchmarked. Also, since this is the first implementation of the features, some modifications can make these features more reliable and faster.</li>
<li>More iterators are to be implemented in order to have a richer NMatrix API.</li>
<li>The issue with slicing needs to be fixed soon. Also, need to standardize the formatting used for slice range specification.</li>
<li>Broadcasting needs to be tested and benchmarked. This will let us improve it&#8217;s reliability and performance. A few APIs could be exposed which would let a user manually broadcast a matrix to a given shape.</li>
<li>NumRuby::Lapack needs to have proper exception handling for LAPACK routines. This will be done by reading the info value returned by routine and raising exception accordingly.</li>
<li>NumRuby::Linalg can be extended to have even more methods.</li>
</ul>


<h2>Acknowledgements</h2>

<p>I wanna thank Ruby Science Foundation, all mentors and org admins for providing me this wonderful opportunity to enhance my knowledge and work on a project. I would also like to thank Google for organizing such a wonderful program due to which I got introduced to Open-source and Ruby Science Foundation. I especially want to thank my mentor Prasun Anand for guiding me through this period, keeping me motivated and for tolerating my procrastination.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2018: RubyPlot GR - A Scientific Plotting Library for Ruby Built on GR Framework]]></title>
    <link href="http://sciruby.com/blog/2019/01/23/gsoc-2018-rubyplot+-gr-+a-scientific-plotting-library-for-ruby-built-on-gr/"/>
    <updated>2019-01-23T18:00:00+05:30</updated>
    <id>http://sciruby.com/blog/2019/01/23/gsoc-2018-rubyplot -gr- a-scientific-plotting-library-for-ruby-built-on-gr</id>
    <content type="html"><![CDATA[<h3>1. About</h3>

<p>For my summer of code Project I decided to create a plotting library.</p>

<p>From scratch.</p>

<p>In Ruby.</p>

<h3>2. Application</h3>

<p>The GSoC 2018 application can be found <a href="https://github.com/pgtgrly/Cairo_Graph/wiki/Google-Summer-of-Code-2018-Application">here</a>.</p>

<h3>3. Code</h3>

<p>The code for the project can be found <a href="https://github.com/pgtgrly/GRruby-extension">here</a>.</p>

<p>RubyPlot is currently being developed <a href="https://github.com/SciRuby/rubyplot">here</a>.</p>

<h3>3. The Plotting Architecture</h3>

<p>The plotting architecture for the library was inspired by Late Dr John Hunter&#8217;s Python Plotting Library &#8220;Matplotlib&#8221;.</p>

<p>The Matplotlib Architecture is be broadly divided into three layers  (as shown in the masterpiece of a figure which I made below). The  Backend, The Artist and the scripting layer.</p>

<p>The Backend layer can further be divided into three parts : The Figure Canvas, The Renderer and the Event.</p>

<p>Matplotlib architecture is mostly written in Python with some of its  backend (the renderer AGG and Figure canvas ) written in C++ ( The  original AGG backend and helper scripts, which is quite tightly bound to  python). But the recently the backends are also written in Python using  the renderers which have Python APIs. The finer details of the Architecture can be found <a href="https://aosabook.org/en/matplotlib.html">here</a>.</p>

<p>In interest of the time I decided to go for a iterative process to develop the Library. I decided to use an existing Artist layer. After a lot of discussion we decided to use GR Framework for the same. The only issue was that GR did not have a Ruby API.</p>

<h3>4. Creating C extensions for GR Framework:</h3>

<p>To create the C extensions I initially decided to use Fiddle followed by FFi. But this lead to certain issues when it came to handling arrays. Hence I decided to go with the old fashioned Ruby C API to create extensions. The code for the same can be found <a href="https://github.com/pgtgrly/GRruby-extension/tree/master/ext/grruby">here</a>.</p>

<h3>5. Creating Scripting Layer</h3>

<p>The Scripting Layer Is meant for high level plotting. The scripting Library created on the GR Framework wrapper has the can plot the following:</p>

<ul>
<li><p>ScatterPlots</p></li>
<li><p>Line graphs</p></li>
<li><p>Bar Plots</p></li>
<li><p>Stacked Bar plot</p></li>
<li><p>Stacked Bar plot (Stacked along z axis)</p></li>
<li><p>Candlestick plots</p>

<p>All the above plots have a lot of customisation options, that can be looked into in the documentation.</p></li>
</ul>


<p>Each Figure can have multiple subplots, each subplot can have multiple plots</p>

<h3>6. Working of the Library</h3>

<p>Here is how the library works.</p>

<p><img src="https://i.imgur.com/sdNg7av.png" alt="Imgur" /></p>

<p>Figure is the class that a user instantiates this is where all the  plotting take place. An instance contains the state of the figure. GR  framework is used as the artist layer which does all the plotting on the  figure. GR is also the backend.</p>

<p>GR artist layer functions are implemented in C language, we wrap the  functions to ruby classes which have the call method which executes the  GR function when the Object of the ruby class is called.
 Each of these ruby classes are called tasks which represents that they  perform a task, for example ClearWorkspace performs the task of cleaning  the workspace.</p>

<p>Now, the figure is divided into subplots. It is Subplot(1,1,1) by  default. So, figure has objects of subplot, each subplot is of type bar  plot or line plot etc. These plots are defined in the Plots module which  is submodule of Scripting module, the Plots module has a submodule  named BasePlots which defines the two bases of plots, LazyBase and  RobustBase.
 Lazy base is for plots which are dependent on state of the figure, for  example a bar graph depends on the location of axes. Every lazy plot has  a unique call function rather than inheriting it from LazyBase. In  LazyPlots the instances of GR Function Classes are called as soon as  they are instantiated. This all is done in the call function.
 Robust base is for plots which are which are independent of the state of  the Figure. For example: A scatter plot is independent of the location  of axes. Plots which are Sub classes of RobustBase append the instances  of GR function classes to tasks when initialized. These instances are  called via the call method defined in RobustBase.</p>

<p>So, each subplot which is of type bar plot or scatter plots etc.  inherits a base. Now, each subplot is just a collection of some tasks,  so it has a task list which stores the tasks to be performed i.e. the  Task objects, for example Scatter plot has tasks SetMarkerColorIndex  which sets the color of the marker, SetMarkerSize which sets the size of  the marker, SetMarkerType which sets the type of the marker and  Polymarker which marks the marker of defined color, size and style.
 Whenever a new Subplot object is initialized, for example  subplot(r,c,i), the figure is divided into a matrix with r rows and c  columns and the subplot initialized with index i is set as the active  subplot ans this active subplot is pushed into the subplot list. Each  subplot object has a unique identity (r,c,i) so if the user wants to  access a subplot which is already declared, this identity will be used.  When the subplot object is called (i.e. to view or save), it first  executes some necessary tasks and then pushes the tasks related to bar  plot, scatter plot, etc. to the task list.</p>

<p>Figure is a collection of such subplots and so Figure has a subplot list which stores the subplot objects.</p>

<p><img src="https://i.imgur.com/H2vEO1i.png" alt="Imgur" /></p>

<p>These tasks are just stored in the lists and are not performed (i.e. called) until the user asks to view or save the figure i.e. when the user calls view or save (which are tasks themselves) the tasks are performed (i.e. called) and the figure is plotted. This is done by using the Module Plotspace.<br/>
When the figure calls the task view or save, these tasks call the Plotspace Object and the state of figure is copied to the Plotspace Object and this Object starts executing( or performing) i.e. calling tasks from task list of each subplot in subplot list and the figure is plotted and viewed or saved.</p>

<p>Here is the current view of Library:</p>

<p><img src="https://i.imgur.com/0HwzAtG.png" alt="imgur" /></p>

<h3>Future</h3>

<p>The Library is currently being developed by SciRuby community <a href="https://github.com/SciRuby/rubyplot">here</a>. Currently, it is a static library, after further development, it&#8217;s Architecture should look like the following:</p>

<p><img src="https://i.imgur.com/AdfPQlT.png" alt="imgur" /></p>

<h3>Acknowledgements</h3>

<p>I would like to thank Sameer Deshmukh and Prasun Anand for guiding me through every step of software design and helping me out through every decision. I would also like to thank Dr John Woods and Dr Pjotr Prins for their valuable feedback. I am glad to be a part of SciRuby community and I hope to further contribute towards it&#8217;s goal.</p>

<p>I would also like to thank Arafat Khan, a fellow GSoCer who worked on the library using Rmagick as the backend renderer for our fruitful debates over the architecture of the library</p>

<p>Finally, I would like to thank Google for giving me this opportunity.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2018 : Ruby Matplotlib]]></title>
    <link href="http://sciruby.com/blog/2019/01/17/gsoc-2018-Ruby-Matplotlib/"/>
    <updated>2019-01-17T05:30:00+05:30</updated>
    <id>http://sciruby.com/blog/2019/01/17/gsoc-2018-Ruby-Matplotlib</id>
    <content type="html"><![CDATA[<p>This is a wrap of my Gsoc project at Sciruby where I worked on builing Matplotlib for Ruby.</p>

<p>At Sciruby, we came across the ambitious task of designing the next Matplotlib for Ruby and so we examined quite a few different plotting libraries and figured that if we could put together ideas from all of these libraries then we can make something really amazing.Primarily our main source of inspiration was Matplotlib. The Matplotlib Architecture is be broadly divided into three layers. The Backend, The Artist and the scripting layer.</p>

<p>Matplotlib architecture is mostly written in Python with some of its backend (the renderer AGG and Figure canvas ) written in C++ ( The original AGG backend and helper scripts, which is quite tightly bound to python). But recently the backends are also written in Python using the renderers which have Python APIs. The finer details of the Architecture can be found <a href="https://www.aosabook.org/en/matplotlib.html">here</a>.</p>

<p>Based on Matplotlib our initial plans for the library can be described in this visual.</p>

<p><img src="https://raw.githubusercontent.com/Arafatk/hagura/gh-pages/images/Screen%20Shot%202019-01-28%20at%201.27.11%20PM.png" alt="Image" /></p>

<p>We decided to build two different ruby libraries independently but with many parallels in their code. Eventually when the project gets completed we will combine them into a single repository and give users the option to use either of the libraries as a backend for construction of the plots.</p>

<p>For the first one, <a href="https://github.com/pgtgrly/GRruby-extension/">Gr plot</a> is plotting library for ruby that uses the <a href="https://gr-framework.org/">GR framework</a> as a backend.
And for the second one, <a href="https://github.com/Arafatk/magick-rubyplot/">Magick plot</a> is a plotting library that produces quality figures in a variety of hardcopy formats using <a href="https://rmagick.github.io/">RMagick</a> as a backend.</p>

<p> Magickplot is an interesting library with many features similar to GRPlot but the internal implementations of both the libraries are radically different. We believe that depending on the use cases the users can find either of them more useful than the other one. 
So our next goal is to merge them together and give users a simple API to switch back ends easily from GR Plot to Magick Plot….</p>

<p>My work in particular dealt with building Magickplot. The library works in similar thought process to painting where you can give it an empty paper called figure canvas and then you draw upon the figure canvas using plotting features. For all drawing and plotting purposes in this library we use RMagick.</p>

<p>So where are our paint brushes and paints for drawing on the plot?</p>

<ul>
<li> draw->rectangle</li>
<li> draw->circle</li>
<li> draw->line</li>
<li> draw->annotate</li>
</ul>


<p>These base features will let you make Bar, Scatter, Dot, Line and Bubble plots with Magickplot with very accurate geometry. A better walk through of the construction of a single plot with this library can be found in this <a href="https://arafatk.github.io/hagura/2018/07/19/bubble-base.html">blog</a>.</p>

<h2>Application</h2>

<p>My GSoC 2018 application for the project can be found <a href="https://docs.google.com/document/d/1t7jJKMaPjFI7pbjfMSG7eh6YmqqIE0qEoXXqsxROlYs/edit?usp=sharing">here</a>.</p>

<h2>Blog Posts</h2>

<p>The entire work for Rubyplot can be summarized in these series of blogposts:</p>

<ul>
<li><a href="https://arafatk.github.io/hagura/2018/06/20/introductions.html">Introductory Blog</a></li>
<li><a href="https://arafatk.github.io/hagura/2018/06/21/ArtistBase-1.html">Artist Base - Part 1</a></li>
<li><a href="https://arafatk.github.io/hagura/2018/06/22/ArtistBase-2.html">Artist Base - Part 3</a></li>
<li><a href="https://arafatk.github.io/hagura/2018/07/11/Plot-Constructions.html">Divisionism</a></li>
<li><a href="https://arafatk.github.io/hagura/2018/07/12/scatter-base.html">Scatter Plots</a></li>
<li><a href="https://arafatk.github.io/hagura/2018/07/19/bubble-base.html">Bubble Plots</a></li>
</ul>


<h2>Future Work</h2>

<p>Our ultimate goal is to make this project similar to a matplotlib equivalent for Ruby with tons of really amazing customization features. I hope you find this interesting and useful.The library is currently being developed by the Sciruby community, feel free to try it out from <a href="https://github.com/SciRuby/rubyplot/">github</a>. Any suggestions and recommendations are welcome.</p>

<h2>FOSS</h2>

<p>I have been an active contributor to a few open source projects and I have started a few
nice ones of my own and I feel really glad to have been introduced to the open
source community. I really appreciate the effort by Google Open Source Committee for conducting GSoC every year. It is the best platform for aspiring programmers to improve their skill and give back to society by developing free and open source software.</p>

<h2>Acknowledgements</h2>

<p>Thanks to all my Mentors from Sciruby namely, Sameer Deshmukh, Pjotr Prins, Prasun Anand and  John Woods. 
Special thanks to Pranav Garg a fellow GSoCer who is the lead developer of GR-Ruby and a student in Gsoc for Sciruby</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2018 : Implementing advance features in daru-view]]></title>
    <link href="http://sciruby.com/blog/2019/01/16/gsoc-2018-advance-features-in-daru-view/"/>
    <updated>2019-01-16T17:30:00+05:30</updated>
    <id>http://sciruby.com/blog/2019/01/16/gsoc-2018-advance-features-in-daru-view</id>
    <content type="html"><![CDATA[<p>This is a wrap of my magnificent adventurous journey of GSoC with SciRuby and I feel proud that I managed to contribute a significant amount to the development and progress of the project <a href="https://github.com/SciRuby/daru-view">daru-view</a>. This post summarizes my work in this period.</p>

<p>Daru-view now presents data in some more visualizations like HighMap and HighStock along with the already implemented HighCharts, GoogleCharts, DataTables and Nyaplot. It provides some more new cool features like formatting Daru::View::Table (GoogleCharts table) with different colors, pattern, etc., exporting charts to different formats, comparing different visualizations in a row and many more. Follow up with these <a href="https://github.com/SciRuby/daru-view/tree/master/spec/dummy_iruby">IRuby examples</a> to know the current features equipped in daru-view.</p>

<p><img src="https://camo.githubusercontent.com/a0a98819e3421378873a96893502e044ceb09e84/68747470733a2f2f33327465657468676c69747465722e66696c65732e776f726470726573732e636f6d2f323031382f30352f68732e706e67" title="Fig. 1: HighStock" alt="HighStock" />
<img src="https://camo.githubusercontent.com/7e99eb68f3901995887d93160f2ef26756b531b5/68747470733a2f2f33327465657468676c69747465722e66696c65732e776f726470726573732e636f6d2f323031382f30352f686d5f696e6469612e706e67" title="Fig. 2: HighMap" alt="HighMap" />
<img src="https://camo.githubusercontent.com/f2d3a7dc5889ec63028cc4d4faeb63c47ba5b270/68747470733a2f2f33327465657468676c69747465722e66696c65732e776f726470726573732e636f6d2f323031382f30352f6373732e706e67" title="Fig. 3: CSS styling in HighCharts" alt="CSS styling" />
<img src="https://camo.githubusercontent.com/c6145397f1bf1756bb2f2921ce35ea0d88b51099/68747470733a2f2f33327465657468676c69747465722e66696c65732e776f726470726573732e636f6d2f323031382f30362f696d706f72745f73707265616473686565742e706e67" title="Fig. 4: Importing Data from Google spreadsheet" alt="Data from spreadsheet" />
<img src="https://camo.githubusercontent.com/5c9e5453dcf25cadceca7f558152bb0f75cdc737/68747470733a2f2f33327465657468676c69747465722e66696c65732e776f726470726573732e636f6d2f323031382f30372f6d756c7469706c655f67635f68632e706e67" title="Fig. 5: Comparing data using different visualizations side by side" alt="Multiple visualizations" /></p>

<p>These figures describes the usage of some of the features implemented in daru-view during GSoC.</p>

<h1>Application</h1>

<p>The GSoC 2018 application can be found <a href="https://docs.google.com/document/d/1id7ZJ4_rAEdXjg2yuBfcwSzV2QIiwpsfgc-gZdOioZ4/edit?usp=sharing">here</a>.</p>

<h1>Code</h1>

<ul>
<li>GSoC 2018 work done summary – <a href="https://github.com/SciRuby/daru-view/wiki/GSoC-2018---Progress-Report">Progress Report</a></li>
<li>GSoC 2018 work presentation – <a href="https://docs.google.com/presentation/d/1lhf3QA5SmqA9YbMAjd6JnSJuZBuAfRKFBYs7JPKPRis/edit?usp=sharing">Advance Features in daru-view</a></li>
<li>Discourse Discussion – <a href="https://discourse.ruby-data.org/t/gsoc-2108-project-advance-features-in-daru-view-discussion/43/50">daru-view discussion</a></li>
</ul>


<p>The work done during this GSoC has been explained in the following eight blog posts:</p>

<ol>
<li><a href="https://32teethglitter.wordpress.com/2018/05/01/gsoc-2018-introduction-advance-features-in-daru-view/">GSoC 2018 Introduction – Goals defined</a></li>
<li><a href="https://32teethglitter.wordpress.com/2018/05/20/gsoc-2018-coding-week-1/">HighCharts and HighMaps</a></li>
<li><a href="https://32teethglitter.wordpress.com/2018/05/27/gsoc-2018-coding-week-2/">Custom Styling CSS in HighCharts</a></li>
<li><a href="https://32teethglitter.wordpress.com/2018/06/08/gsoc-2018-coding-week-3-4/">Exporing HighCharts | ChartWrapper | Importing data from google spreadsheet in Google Charts</a></li>
<li><a href="https://32teethglitter.wordpress.com/2018/06/24/gsoc-2018-coding-week-5-6/">Exporting Google Charts | Charteditor</a></li>
<li><a href="https://32teethglitter.wordpress.com/2018/07/08/gsoc-2018-coding-week-7-8/">Handling events in Google Charts | Multiple Charts in a row</a></li>
<li><a href="https://32teethglitter.wordpress.com/2018/07/24/gsoc-2018-coding-week-9-10/">Formatters in Google Charts | Loading large set of data in DataTables</a></li>
<li><a href="https://32teethglitter.wordpress.com/2018/08/06/gsoc-2018-coding-week-11-12/">Reduce a bunch of lines due to JS files in source HTML in rails | Rake task to add new adapter</a></li>
</ol>


<h1>Future Work</h1>

<p>The future work involves removing the dependency of daru-view on gems <code>google_visualr</code> and <code>lazy_high_charts</code> by creating our own gems. Check out these <a href="https://github.com/SciRuby/daru-view/wiki/Ideas#new-ideas-to-be-reviewed">new ideas</a> that can be implemented in daru-view.</p>

<h1>FOSS</h1>

<p>This has been my first attempt to explore the open source community. The summer was filled with the development of open source software and definitely was a great learning experience.</p>

<p>I really appreciate the effort by Google Open Source Committee for conducting GSoC every year. It is the
best platform for the aspiring programmers to improve their skill and give back to society by developing free
and open source software.</p>

<h1>Acknowledgements</h1>

<p>I would like to express my sincere gratitude to Ruby Science Foundation, all the mentors and org admins for providing me this wonderful opportunity to enhance my knowledge and work independently on a project. I especially want to thank Shekhar for guiding me through the journey, helping and motivating me in every possible way.</p>

<p>I am very thankful to Google for organizing such an awesome program.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2017 : Creating the fastest Math libraries for Ruby by using the GPU through OpenCL, CUDA and ArrayFire.]]></title>
    <link href="http://sciruby.com/blog/2017/09/15/gsoc-2017-fastest-ruby-math-libraries/"/>
    <updated>2017-09-15T22:46:00+05:30</updated>
    <id>http://sciruby.com/blog/2017/09/15/gsoc-2017-fastest-ruby-math-libraries</id>
    <content type="html"><![CDATA[<p>GSoC 2017 is about to end. This post summarises my work during the course of summer.</p>

<p>ArrayFire-rb now supports linear algebra on GPU and CPU. Currently only double dtype has been implemented.
It supports dense and sparse matrices. It has multiple backends namely, CUDA, OpenCL and CPU.</p>

<p><img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/arrayfire/add.png?raw=true" title="Fig. 1: Matrix Addition" alt="Matrix Addition" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/arrayfire/sub.png?raw=true" title="Fig. 2: Matrix Subtraction" alt="Matrix Subtraction" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/arrayfire/mult.png?raw=true" title="Fig. 3: Matrix Multiplication" alt="Matrix Multiplication" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/arrayfire/det.png?raw=true" title="Fig. 4: Matrix Determinant" alt="Matrix Determinant" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/arrayfire/lu.png?raw=true" title="Fig. 5: LU Decomposition" alt="LU Decomposition" /></p>

<p>(Note: The above benchmarks have been done on an AMD FX 8350 octacore processor and Nvidia GTX 750Ti GPU. CUDA backend of ArrayFire was used with double floating points.)</p>

<p>The figure shows that ArrayFire takes the least computation time of all. For elementwise arithmetic operations, ArrayFire is 2 e 4 times faster than NMatrix for Ruby whereas 2 e 3 times faster than NMatrix for JRuby.</p>

<p>The figure shows that ArrayFire takes the least computation time of all. ArrayFire is 3 e +6 times faster than NMatrix for JRuby and NMatrix for Ruby(not BLAS) whereas 7 e +5 times faster than NMatrix for Ruby(using BLAS).</p>

<p>For LAPACK routines, like calculating determinant and lower-upper factorization, ArrayFire is 100 times faster than NMatrix for JRuby whereas 6 times faster than NMatrix for Ruby(using LAPACKE).</p>

<h1>Application</h1>

<p>The GSoC 2017 application can be found <a href="https://github.com/prasunanand/resume/wiki/GSoC-2017-proposal">here</a>.</p>

<h1>Code</h1>

<p><a href="https://github.com/prasunanand/arrayfire-rb">ArrayFire-rb</a>: The <a href="https://github.com/arrayfire/arrayfire-rb/pull/3">pull request</a> is undergoing a review.</p>

<p>ArrayFire-rb Benchmarks: Codebase can be found <a href="https://github.com/prasunanand/arrayfire-rb-benchmark-suite">here</a>.</p>

<p>Bio::FasterLmmD : Codebase can be found <a href="https://github.com/prasunanand/bio-faster_lmm_d">here</a></p>

<p>The work on creating the bindings have been explained in the following nine blog posts:</p>

<ol>
<li><a href="http://www.prasunanand.com/ruby-c-extensions/2017/06/23/gsoc17-ruby-c-extensions-for-complex-projects.html">Ruby C extensions for complex projects</a></li>
<li><a href="http://www.prasunanand.com/arrayfire/2017/06/23/gsoc17-arrayfire-ruby-bindings-part-1-installation.html">Installation</a></li>
<li><a href="http://www.prasunanand.com/arrayfire/2017/07/04/gsoc17-arrayfire-ruby-bindings-part-2-af_array.html">Af_Array</a>(see performance)</li>
<li><a href="http://www.prasunanand.com/arrayfire/2017/07/22/gsoc17-arrayfire-ruby-bindings-part-3-minitest-algorithm.html">Test-suite and Algorithm class</a></li>
<li><a href="http://www.prasunanand.com/arrayfire/2017/08/16/gsoc17-arrayfire-ruby-bindings-part-4-blas-lapack.html">BLAS and LAPACK routines</a>(see performance)</li>
<li><a href="http://www.prasunanand.com/arrayfire/2017/08/17/gsoc17-arrayfire-ruby-bindings-part-4-statistics-and-random-engine.html">Statistics and Random Engine routines</a></li>
<li><a href="http://www.prasunanand.com/arrayfire/2017/08/22/gsoc17-arrayfire-ruby-bindings-part-6-device.html">Device and Util</a></li>
<li><a href="http://www.prasunanand.com/arrayfire/2017/08/24/gsoc17-arrayfire-ruby-bindings-part-7-backend-cuda-and-opencl.html">Multiple Backends: CUDA, OpenCL and CPU</a></li>
<li><a href="http://www.prasunanand.com/arrayfire/2017/08/24/gsoc17-arrayfire-ruby-bindings-part-8-nmatrix-interface.html">ArrayFire-NMatrix Interface</a></li>
</ol>


<p>I took a side-track working on <code>Bio::FasterLmmD</code> . This work is not complete and still in progress.
It is an effort to <code>call D from Ruby</code>. The work has been explained in a previous <a href="http://sciruby.com/gpu-computing/2017/07/25/gsoc17-calling-d-from-ruby-for-gpu-computing.html">blog post</a>.</p>

<p>The work on ArrayFire-rb - JRuby has been postponed for now as I wanted to concentrate on MRI for
the best results.</p>

<h1>Future Work</h1>

<p>The future work involves improving the ArrayFire-rb code and writing tutorials. ArrayFire is not limited to
linear algebra so I will create bindings for Signal Processing, Computer Vision, etc. I will also add support
for data types other than <code>double</code>.</p>

<p>The work on ArrayFire-rb - JRuby will begin as soon as ArrayFire gem is published.</p>

<h1>FOSS</h1>

<p>This has been my second GSoC with SciRuby. It has been more than an year contibuting extensively to FOSS.</p>

<p>I really appreciate the effort by Google Open Source Committee for conducting GSoC every year. It is the
best platform for the aspiring programmers improve their skill and give back to society by developing free
and open source software.</p>

<p>Last year&#8217;s GSoC work helped me to present a talk at FOSDEM 2017 and Ruby Conf India 2017.  I got active
in the Indian Ruby Community. Recently, I have been invited as a speaker to Ruby World Conference 2017, Matsue, Japan
and RubyConf 2017, New Orleans, to talk on &#8220;GPU computing with Ruby&#8221;.</p>

<p>I plan to continue contributing to open source, strive for improving my skills, and help new programmers
contribute to FOSS. I would be glad if I could mentor students for upcoming GSoCs.</p>

<h1>Acknowledgements</h1>

<p>I would like to express my sincere gratitude to my mentor Pjotr Prins, for his guidance, patience and support.
I have learn a lot from him since my last GSoC and still learning. I couldn&#8217;t have hoped for a better mentor.</p>

<p>I am grateful to Google and the Ruby Science Foundation for this golden opportunity.</p>

<p>I am very thankful to John Woods, Sameer Deshmukh, Alexej Gossmann, Gaurav Tamba and Pradeep Garigipati
who mentored me through the project.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2017 : Data visualization using daru-view]]></title>
    <link href="http://sciruby.com/blog/2017/09/01/gsoc-2017-data-visualization-using-daru-view/"/>
    <updated>2017-09-01T22:46:00+05:30</updated>
    <id>http://sciruby.com/blog/2017/09/01/gsoc-2017-data-visualization-using-daru-view</id>
    <content type="html"><![CDATA[<p>Hello, Rubyist! Are looking for good ruby gem for interactive data
visualization? Then you must try <a href="https://github.com/Shekharrajak/daru-view"><code>daru-view</code></a>, a plugin gem for <a href="https://github.com/SciRuby/daru"><code>daru</code></a>.</p>

<h2>What makes daru-view different ?</h2>

<ul>
<li><p><code>daru-view</code> is designed for interactive plotting of charts and tables.It
provide different plotting tools like Nyaplot, HighCharts, GoogleCharts,
DataTable. So you don&#8217;t have to write any JavaScript code from these sites
and no need to shift to other language to get charts.</p></li>
<li><p>It can work with <strong>any ruby web application framework like Rails/Sinatra/Nanoc/Hanami</strong>. If you want to try few examples then please look into the
<a href="https://github.com/Shekharrajak/daru-view/tree/master/spec"><code>daru-view/spec/dummy_*</code></a> examples of Rails, Sinatra, Nanoc web applications.</p></li>
<li><p>Now Ruby developers are using IRuby notebook for interactive programming.
<code>daru-view</code> support IRuby notebook as well. So if you just want to see chart
for some DataFrame or Array of data, you can use <code>daru-view</code>.</p></li>
<li><p><code>daru-view</code> can generate chart images to download and save.</p></li>
<li><p><code>daru-view</code> adapters <code>googlecharts</code>, <code>highcharts</code> are able to geneate 3D charts as well.</p></li>
<li><p><code>Table</code> have some main features like pagination, search and many more to be added.It is
designed to load large data set smoothly.</p></li>
</ul>


<h2>Introduction</h2>

<p>Daru is doing pretty good work as the data analysis &amp; manipulation in IRuby notebook as well as backend part of web application. Ruby web application frameworks like Ruby on Rails, Sinatra, Nanoc are popular frameworks. So if Ruby developers get the gem like daru which can do data analysis
and visualization work in applications, then there is no need of shifting to another language or usage of other gem.</p>

<p>My project for <abbr title="Google Summer of Code 2017"> GSoC 2017</abbr> was to &#8220;make Daru more ready for integration with modern Web framework&#8221; in terms of visualization.</p>

<p>To improve in terms of viewing data,
<a href="https://github.com/Shekharrajak/daru-view">daru-view</a>, a plugin gem for
<a href="https://github.com/SciRuby/daru">daru</a> is created. <a href="https://github.com/Shekharrajak/daru-view">daru-view</a> is for easy and interactive plotting in web application &amp; IRuby notebook. It can work in frameworks like Rails, Sinatra, Nanoc and hopefully in others too.</p>

<p>To see a quick overview of daru-view&#8217;s features, have a look at these examples:</p>

<ul>
<li><p><a href="http://nbviewer.jupyter.org/github/shekharrajak/daru-view/tree/master/spec/dummy_iruby/">IRuby Notebook Examples</a></p></li>
<li><p><a href="https://github.com/Shekharrajak/daru_examples_io_view_rails">daru io and daru-view usage in Rails app</a></p></li>
<li><p><a href="https://github.com/Shekharrajak/daru-view/blob/master/README.md">README of daru-view</a></p></li>
</ul>


<h2>Examples</h2>

<p>This is how we can create a Plot class object:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Plot</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li><p><code>data</code> can be <code>Daru::DataFrame</code>, data array or the format that the adapter support.</p></li>
<li><p><code>options</code> is a hash that contains various options to customize the chart.
If you have chosen a plotting library then you must use the options according
to the options the library providing. Here is the library <code>daru-view</code> uses.
Please check the examples options, they are passing in javascript code:</p>

<ul>
<li><p>GoogleCharts: <a href="https://developers.google.com/chart/interactive/docs/gallery">https://developers.google.com/chart/interactive/docs/gallery</a></p></li>
<li><p>HighCharts: <a href="https://www.highcharts.com/demo">https://www.highcharts.com/demo</a></p></li>
<li><p>Nyaplot: <a href="https://github.com/SciRuby/nyaplot">https://github.com/SciRuby/nyaplot</a> (it works same as <code>daru</code>)</p></li>
</ul>
</li>
</ul>


<p>Note: User must have some knowledge about the plotting tool(that you want to
use) to use it in <code>daru-view</code>. So that you can pass the correct options.</p>

<h3>GoogleCharts:</h3>

<p>Set the plotting library to <code>:googlecharts</code> to use this adapter. This will
load the required js files in your webpage or IRuby notebook.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;daru/view&#39;</span>
</span><span class='line'><span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">.</span><span class="n">plotting_library</span> <span class="o">=</span> <span class="ss">:googlecharts</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let&#8217;s create a DataFrame :</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">idx</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">Index</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="s1">&#39;Year&#39;</span><span class="p">,</span> <span class="s1">&#39;Sales&#39;</span><span class="o">]</span>
</span><span class='line'><span class="n">data_rows</span> <span class="o">=</span> <span class="o">[</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;2004&#39;</span><span class="p">,</span>  <span class="mi">1000</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;2005&#39;</span><span class="p">,</span>  <span class="mi">1170</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;2006&#39;</span><span class="p">,</span>  <span class="mi">660</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;2007&#39;</span><span class="p">,</span>  <span class="mi">1030</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="n">df_sale_exp</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">DataFrame</span><span class="o">.</span><span class="n">rows</span><span class="p">(</span><span class="n">data_rows</span><span class="p">)</span>
</span><span class='line'><span class="n">df_sale_exp</span><span class="o">.</span><span class="n">vectors</span> <span class="o">=</span> <span class="n">idx</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># perform data manipulations, if you want.</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now time to plot it:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">line_basic_chart</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Plot</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">df_sale_exp</span><span class="p">)</span>
</span><span class='line'><span class="n">line_basic_chart</span><span class="o">.</span><span class="n">chart</span>
</span></code></pre></td></tr></table></div></figure>


<p>This will return the chart object we created using GoogleCharts.
In IRuby notebook, you will see this:</p>

<p><img src="https://github.com/Shekharrajak/gsoc_2017_blog/blob/master/img/googlecharts_line1.png?raw=true" title="Basic line chart using GoogleCharts" alt="Basic line chart using GoogleCharts"></p>

<p>You can find the IRuby notebook example in <a href="http://nbviewer.jupyter.org/github/shekharrajak/daru-view/blob/master/spec/dummy_iruby/Google%20Chart%20%7C%20%20Line%20Chart.ipynb">this link</a>.</p>

<p>These are various charts type we can use e.g. line, area, bar, bubble,
candlestick, combo, histogram, org, pie, stepped area chart, timeline, treemap,
gauge, column, scatter, etc. We can find the customization options in the
<a href="https://developers.google.com/chart/interactive/docs/gallery">google charts site</a>.</p>

<p>Let me try another chart type Geo :</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">country_population</span> <span class="o">=</span> <span class="o">[</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;Germany&#39;</span><span class="p">,</span> <span class="mi">200</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;United States&#39;</span><span class="p">,</span> <span class="mi">300</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;Brazil&#39;</span><span class="p">,</span> <span class="mi">400</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;Canada&#39;</span><span class="p">,</span> <span class="mi">500</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;France&#39;</span><span class="p">,</span> <span class="mi">600</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;RU&#39;</span><span class="p">,</span> <span class="mi">700</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">df_cp</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">DataFrame</span><span class="o">.</span><span class="n">rows</span><span class="p">(</span><span class="n">country_population</span><span class="p">)</span>
</span><span class='line'><span class="n">df_cp</span><span class="o">.</span><span class="n">vectors</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">Index</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="s1">&#39;Country&#39;</span><span class="p">,</span> <span class="s1">&#39;Population&#39;</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">geochart</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Plot</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
</span><span class='line'>    <span class="n">df_cp</span><span class="p">,</span> <span class="ss">type</span><span class="p">:</span> <span class="ss">:geo</span><span class="p">,</span> <span class="ss">adapter</span><span class="p">:</span> <span class="ss">:googlecharts</span>
</span><span class='line'><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note: If you have already loaded the dependent JS files for the library then you can use <code>adapter: :googlecharts</code> in your Plot initialization.</p>

<p><img src="https://github.com/Shekharrajak/gsoc_2017_blog/blob/master/img/googlechart_geo1.png?raw=true" title="Basic Geo chart using GoogleCharts" alt="Basic Geo chart using GoogleCharts"></p>

<h3>HighCharts:</h3>

<p>Set the plotting library to <code>:highcharts</code> to use this adapter. This will
load the required js files in your webpage or IRuby notebook.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;daru/view&#39;</span>
</span><span class='line'><span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">.</span><span class="n">plotting_library</span> <span class="o">=</span> <span class="ss">:highcharts</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let&#8217;s pass the <code>data</code> as HighCharts support (we can pass a DataFrame as well):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">data</span> <span class="o">=</span> <span class="o">[</span>
</span><span class='line'>    <span class="o">[</span><span class="s1">&#39;Firefox&#39;</span><span class="p">,</span>   <span class="mi">45</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="o">[</span><span class="s1">&#39;IE&#39;</span><span class="p">,</span>       <span class="mi">26</span><span class="o">.</span><span class="mi">8</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>       <span class="ss">:name</span><span class="o">=&gt;</span> <span class="s1">&#39;Chrome&#39;</span><span class="p">,</span>
</span><span class='line'>       <span class="ss">:y</span><span class="o">=&gt;</span> <span class="mi">12</span><span class="o">.</span><span class="mi">8</span><span class="p">,</span>
</span><span class='line'>       <span class="ss">:sliced</span><span class="o">=&gt;</span> <span class="kp">true</span><span class="p">,</span>
</span><span class='line'>       <span class="ss">:selected</span><span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'>    <span class="p">},</span>
</span><span class='line'>    <span class="o">[</span><span class="s1">&#39;Safari&#39;</span><span class="p">,</span>    <span class="mi">8</span><span class="o">.</span><span class="mi">5</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="o">[</span><span class="s1">&#39;Opera&#39;</span><span class="p">,</span>     <span class="mi">6</span><span class="o">.</span><span class="mi">2</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="o">[</span><span class="s1">&#39;Others&#39;</span><span class="p">,</span>   <span class="mi">0</span><span class="o">.</span><span class="mi">7</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span><span class='line'><span class="n">plt_pie</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Plot</span><span class="o">.</span><span class="n">new</span> <span class="n">data</span><span class="p">,</span> <span class="ss">type</span><span class="p">:</span> <span class="ss">:pie</span>
</span></code></pre></td></tr></table></div></figure>


<p>This will return the <code>Plot</code> object we created.
In IRuby notebook, you will see this:</p>

<p><img src="https://github.com/Shekharrajak/gsoc_2017_blog/blob/master/img/highcharts_pie.png?raw=true" title="Basic pie chart using HighCharts" alt="Basic pie chart using HighCharts"></p>

<p>You can find the IRuby notebook example in <a href="http://nbviewer.jupyter.org/github/shekharrajak/daru-view/blob/master/spec/dummy_iruby/HighCharts-%20Pie%20charts.ipynb">this link</a>.</p>

<p>There are various charts type we can use e.g. line, area, bar, bubble,
dynamic chart, pie, column, scatter, etc. We can find the customization options in the
<a href="https://www.highcharts.com/demo">HighCharts site</a>.</p>

<h3>Nyaplot</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;daru/view&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#  set adapter</span>
</span><span class='line'><span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">.</span><span class="n">plotting_library</span> <span class="o">=</span> <span class="ss">:nyaplot</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># define dataframe</span>
</span><span class='line'><span class="n">df</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">DataFrame</span><span class="o">.</span><span class="n">new</span><span class="p">({</span>
</span><span class='line'>  <span class="ss">a</span><span class="p">:</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">23</span><span class="p">,</span> <span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">b</span><span class="p">:</span> <span class="o">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="o">-</span><span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">c</span><span class="p">:</span> <span class="o">[</span><span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;II&#39;</span><span class="p">,</span> <span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;III&#39;</span><span class="p">,</span> <span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;III&#39;</span><span class="p">,</span> <span class="s1">&#39;II&#39;</span><span class="o">]</span>
</span><span class='line'>  <span class="p">})</span>
</span><span class='line'><span class="n">df</span><span class="o">.</span><span class="n">to_category</span> <span class="ss">:c</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># creating scatter chart</span>
</span><span class='line'><span class="n">scatter_chart</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Plot</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="ss">type</span><span class="p">:</span> <span class="ss">:scatter</span><span class="p">,</span> <span class="ss">x</span><span class="p">:</span> <span class="ss">:a</span><span class="p">,</span> <span class="ss">y</span><span class="p">:</span> <span class="ss">:b</span><span class="p">,</span> <span class="ss">categorized</span><span class="p">:</span> <span class="p">{</span><span class="ss">by</span><span class="p">:</span> <span class="ss">:c</span><span class="p">,</span> <span class="nb">method</span><span class="p">:</span> <span class="ss">:color</span><span class="p">})</span>
</span></code></pre></td></tr></table></div></figure>


<p>In IRuby notebook:</p>

<p><img src="https://github.com/Shekharrajak/gsoc_2017_blog/blob/master/img/nyaplot_scatter.png?raw=true" title="Basic scatter chart using Nyaplot" alt="Basic scatter chart using Nyaplot"></p>

<h3>GoogleChart data table</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;daru/view&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#  set adapter</span>
</span><span class='line'><span class="c1"># You don&#39;t need this line if you have already using google chart for plotting.</span>
</span><span class='line'><span class="c1"># It is just for loading the dependent js files.</span>
</span><span class='line'><span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">.</span><span class="n">table_library</span> <span class="o">=</span> <span class="ss">:googlechart</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Lets use array as `data` (we can pass Daru::DataFrame as well)</span>
</span><span class='line'><span class="n">data</span> <span class="o">=</span> <span class="o">[</span>
</span><span class='line'>  <span class="o">[</span><span class="s1">&#39;Galaxy&#39;</span><span class="p">,</span> <span class="s1">&#39;Distance&#39;</span><span class="p">,</span> <span class="s1">&#39;Brightness&#39;</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;Canis Major Dwarf&#39;</span><span class="p">,</span> <span class="mi">8000</span><span class="p">,</span> <span class="mi">230</span><span class="o">.</span><span class="mi">3</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;Sagittarius Dwarf&#39;</span><span class="p">,</span> <span class="mi">24000</span><span class="p">,</span> <span class="mi">4000</span><span class="o">.</span><span class="mi">5</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;Ursa Major II Dwarf&#39;</span><span class="p">,</span> <span class="mi">30000</span><span class="p">,</span> <span class="mi">1412</span><span class="o">.</span><span class="mi">3</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;Lg. Magellanic Cloud&#39;</span><span class="p">,</span> <span class="mi">50000</span><span class="p">,</span> <span class="mi">120</span><span class="o">.</span><span class="mi">9</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="o">[</span><span class="s1">&#39;Bootes I&#39;</span><span class="p">,</span> <span class="mi">60000</span><span class="p">,</span> <span class="mi">1223</span><span class="o">.</span><span class="mi">1</span><span class="o">]</span>
</span><span class='line'>  <span class="o">]</span>
</span><span class='line'><span class="n">galaxy_table</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Table</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span><span class='line'><span class="n">galaxy_table</span><span class="o">.</span><span class="n">table</span>
</span></code></pre></td></tr></table></div></figure>


<p>This will return the table object we created using GoogleCharts tool.
In IRuby notebook, you will see this:</p>

<p><img src="https://github.com/Shekharrajak/gsoc_2017_blog/blob/master/img/googlechart_table1.png?raw=true" title="Basic table using GoogleCharts" alt="Basic table using GoogleCharts"></p>

<p>We can create table using Vectors as well.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">dv</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">Vector</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="mi">43934</span><span class="p">,</span> <span class="mi">52503</span><span class="p">,</span> <span class="mi">57177</span><span class="p">,</span> <span class="mi">69658</span><span class="p">,</span> <span class="mi">97031</span><span class="p">,</span> <span class="mi">119931</span><span class="p">,</span> <span class="mi">137133</span><span class="p">,</span> <span class="mi">154175</span><span class="o">]</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># adding pagination and some customization [optional]</span>
</span><span class='line'><span class="n">opts_pagination</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>  <span class="ss">width</span><span class="p">:</span> <span class="s1">&#39;100%&#39;</span><span class="p">,</span> <span class="ss">height</span><span class="p">:</span> <span class="s1">&#39;100%&#39;</span> <span class="p">,</span>
</span><span class='line'>  <span class="ss">pageSize</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="n">table_vec</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Table</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">dv</span><span class="p">,</span> <span class="n">opts_pagination</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>In Ruby Notebook:</p>

<p><img src="https://github.com/Shekharrajak/gsoc_2017_blog/blob/master/img/googlechart_vec_table1.png?raw=true" title="Basic vector table using GoogleCharts" alt="Basic vector table using GoogleCharts"></p>

<h3>DataTable</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;daru/view&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#  set adapter.</span>
</span><span class='line'><span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">.</span><span class="n">table_library</span> <span class="o">=</span> <span class="ss">:datatables</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Lets use Daru::DataFrame as `data` (we can pass Array as well)</span>
</span><span class='line'><span class="n">df</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">DataFrame</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="ss">b</span><span class="p">:</span> <span class="o">[</span><span class="mi">11</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">14</span><span class="p">,</span><span class="mi">15</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="ss">a</span><span class="p">:</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="ss">c</span><span class="p">:</span> <span class="o">[</span><span class="mi">11</span><span class="p">,</span><span class="mi">22</span><span class="p">,</span><span class="mi">33</span><span class="p">,</span><span class="mi">44</span><span class="p">,</span><span class="mi">55</span><span class="o">]</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>    <span class="ss">order</span><span class="p">:</span> <span class="o">[</span><span class="ss">:a</span><span class="p">,</span> <span class="ss">:b</span><span class="p">,</span> <span class="ss">:c</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="ss">index</span><span class="p">:</span> <span class="o">[</span><span class="ss">:one</span><span class="p">,</span> <span class="ss">:two</span><span class="p">,</span> <span class="ss">:three</span><span class="p">,</span> <span class="ss">:four</span><span class="p">,</span> <span class="ss">:five</span><span class="o">]</span>
</span><span class='line'><span class="p">)</span>
</span><span class='line'><span class="n">df_datatable</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Table</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="ss">pageLength</span><span class="p">:</span> <span class="mi">3</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Currently there is some problem to diplay it in IRuby notebook, but in web application
you can see something like this using <code>df_datatable.div</code> :</p>

<p><img src="https://github.com/Shekharrajak/gsoc_2017_blog/blob/master/img/datatables_basic1.png?raw=true" title="Basic table using Datatables" alt="Basic table using Datatables"></p>

<h2>How to use it in Ruby web application</h2>

<p>As we know, we can get the HTML, JS code for the chart from the
<code>Daru::View::Plot</code> or <code>Daru:View::Table</code> object using <code>#div</code> method. So just
need to add that HTML, JS code in webpage in proper place.</p>

<p>There is few things to be noted:</p>

<ol>
<li><p>In layout of the webpage, you have to load all the dependent JS files.
So that HTML, JS code that is genearted work smoothly in that webpage. You
can load the dependent js file for nyaplot library using <code>Daru::View.dependent_script(:nyaplot)</code>, similarly for other library.</p></li>
<li><p>If you are using multiple library in one webpage then load multiple
dependent JS files, in that webpage layout (generally in head tag).</p></li>
</ol>


<p>We can set default adapter using <code>Daru::View.plotting_library = :googlecharts</code>
and also we can change it for particular object while initializing object,
i.e. <code>Daru::View::Plot.new(data, {adapter: :googlecharts})</code>. Just we have
to make sure that dependent JS files are loaded for it.</p>

<p>To make it easy, we have defined <code>daru_chart</code> (that works same as Daru::View::Plot.new) , <code>daru_table</code> (works same as Daru::View::Table.new) for Rails application.</p>

<p>So you can easily use it in controller or view of the application. For reference you can check the <a href="https://github.com/Shekharrajak/daru_examples_io_view_rails">demo Rails app</a>.</p>

<h2>Design of daru-view</h2>

<p><a href="https://github.com/Shekharrajak/daru-view">daru-view</a>, currently using
<a href="https://github.com/SciRuby/nyaplot">Nyaplot</a>, <a href="https://www.highcharts.com/">HighCharts</a>, <a href="https://developers.google.com/chart/interactive/docs/gallery">GoogleCharts</a> for plotting the charts. It is also
generating tables using <a href="https://datatables.net/">DataTables</a> and <a href="https://developers.google.com/chart/interactive/docs/gallery">GoogleCharts</a> with pagination, search and various features.</p>

<h3>Design Pattern in daru-view</h3>

<p>daru-view mainly uses the <a href="https://en.wikipedia.org/wiki/Adapter_pattern">adapter design pattern</a> and <a href="https://en.wikipedia.org/wiki/Composite_pattern">composite design pattern</a>.</p>

<ul>
<li><p><strong>Why Adapter design pattern:</strong></p>

<ul>
<li><p>Adapter pattern’s motivation is that we can reuse existing gems if we can modify the interface.</p></li>
<li><p>daru-view joins functionalities of independent or incompatible interfaces of different gems.</p></li>
<li><p><code>daru-view</code> have <a href="https://github.com/Shekharrajak/daru-view/blob/master/lib/daru/view/plot.rb"><code>Plot</code></a> and <a href="https://github.com/Shekharrajak/daru-view/blob/master/lib/daru/view/table.rb"><code>Table</code></a> class, which are using a <a href="https://github.com/Shekharrajak/daru-view/tree/master/lib/daru/view/adapters">adapter</a> when adapter(library to be used for plotting) is set for <code>Plot</code>, <code>Table</code> instance.</p></li>
</ul>
</li>
<li><p><strong>Why Composite design pattern:</strong></p>

<ul>
<li><p>To define common objects and use it for defining composite objects.</p></li>
<li><p>In <code>daru-view</code> we try to write common functions in a module and include it whenever needed.</p></li>
</ul>
</li>
</ul>


<h2>Implementation</h2>

<p>daru-view ensure that it&#8217;s functions are usable in both IRuby notebook as well
as ruby web application frameworks.</p>

<p>The main thing we need to display something in web application or IRuby
notebook is <code>HTML</code> code of it. daru-view generates the <code>HTML</code> code of the
chart, table and the same can be used to display in web application &amp; IRuby
notebook.</p>

<p>These are the libraries which is used in daru-view currently:</p>

<h3>Nyaplot</h3>

<p><a href="https://github.com/SciRuby/nyaplot">Nyaplot</a> is good library for
visualization in IRuby notebook only. When we use Nyaplot as the adapter in
daru-view, it is usable in both IRuby notebook and web applications. Daru
DataFrame or Vector is used as the data source of the chart. It works
similar to the initial <code>daru</code> plotting system.</p>

<p>If user want to use the Nyaplot methods then it can be done on Nyaplot object.We
can get nyplot object using <code>daru_plot_obj.chart</code>.</p>

<p>i.e.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">daru_view_obj</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">View</span><span class="o">::</span><span class="no">Plot</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
</span><span class='line'>                  <span class="n">daru_dataframe</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="ss">adapter</span><span class="p">:</span> <span class="ss">:nyaplot</span><span class="p">})</span>
</span><span class='line'><span class="n">nyaplot_obj</span> <span class="o">=</span> <span class="n">daru_view_obj</span><span class="o">.</span><span class="n">chart</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now user can operate all the methods for Nyaplot object. Same thing is for
all other adapter in daru-view.</p>

<h3>HighCharts</h3>

<p>To add the <a href="https://www.highcharts.com/">HighCharts</a> features for plotting various chart types, daru-view uses the <a href="https://github.com/michelson/lazy_high_charts">lazy_high_charts</a> gem with additional features.</p>

<p>In this adapter data source can be Array of data, Daru::DataFrame, Daru::Vector or HTML table code of the data.</p>

<p>There are various of options in HighCharts. One can see the options that can
be used in <a href="https://www.highcharts.com/demo">HighCharts demo link</a>, which can
be directly used in daru-view Plot.</p>

<p><strong>HighCharts adaptor can work offline as well in daru-view. Developers can update the saved the JS files (in daru-view) using rake task automatically.</strong></p>

<p>If you is familiar with <code>lazy_high_chart</code> gem and want to use it for
config the chart then user can access the <code>lazy_high_chart</code> object using
<code>Daru::View::Plot#chart</code> and can do necessary operations.</p>

<h3>GoogleCharts</h3>

<p>To add the <a href="https://developers.google.com/chart/interactive/docs/gallery">GoogleCharts</a> features for plotting various chart types, daru-view uses the <a href="https://github.com/winston/google_visualr/">google_visualr</a> gem with additional features(in this module more new features are updated).</p>

<p>We want GoogleChart adapter to be very strong since Google chart tools always gets updated and it has amazing plotting features. Similar to the HighCharts module, here also we can use all the options described in Google Charts website.</p>

<p>User can access the <code>google_visualr</code> object using <code>Daru::View::Plot#chart</code>, if
they want to operate <code>google_visualr</code> methods.</p>

<h4>GoogleCharts as data table</h4>

<p>One of the good thing about google chart tool is, it can be used for generating table
for web application and IRuby Notebook with pagination and other features.</p>

<p><strong><code>Daru::View::Plot</code> can take data Array, Daru::DataFrame, Daru::Vector,
Daru::View::Table as data source.</strong></p>

<p><strong><code>Daru::View::Table</code> can take data Array, daru DataFrame, Daru Vector as data
 source.</strong></p>

<h3>DataTables</h3>

<p><a href="https://datatables.net/">DataTables</a> has interaction controls to any HTML table. It can handle large set of data and have many cool features.</p>

<p>To use it, daru-view uses <a href="https://github.com/Shekharrajak/data_tables">https://github.com/Shekharrajak/data_tables</a> gem. [Note: the gem name will be changed in near future]</p>

<p>It basically uses the HTML table code and add features that user want. So internally HTML table code of Daru::DataFrame and Daru::Vector is passed as data source parameter.</p>

<h2>Future Work</h2>

<p>daru-view will be more powerful and simple in near future. Developers can add
more libraries in daru-view easily, if required. To add library follow the setups given in
<a href="https://github.com/Shekharrajak/daru-view/blob/master/CONTRIBUTING.md">CONTRIBUTING.md</a></p>

<h2>Conclusion</h2>

<p>The aim of the daru-view is to plot charts in IRuby notebook and ruby web
application easily, so that developers need not have to use any other gem or
language for visualization.</p>

<p>It can work smoothly in Rails/Sinatra/Nanoc web frameworks and I hope it can work in other ruby frameworks as well, because daru-view is generating the html code and javascript code for the chart, which is basic need of the webpage.</p>

<p><strong>Why not use the plotting libraries directly?</strong></p>

<p>If you are using daru gem for analyzing the data and want to visualize it, then it will be good if you have data-visualization within daru and can plot it directly using DataFrame/Vector objects of daru.</p>

<p>daru-view will be helpful in plotting charts and tables directly from the Daru::DataFrame and Daru::Vector . daru-view using nyaplot, highcharts , google charts right now to plot the chart. So user can set the plotting library and get the chart accordingly.</p>

<p>Most of the plotting libraries doesn&#8217;t provide the features of plotting charts in iruby notebook. They are defined only for web applications (mostly for Rails). But daru-view can plot charts in any ruby web application as well as iruby notebook.</p>

<h2>Acknowledgements</h2>

<p>I would like to thank to my mentors <a href="https://github.com/v0dro">Sameer Deshmukh</a>
,<a href="https://github.com/lokeshh">Lokesh Sharma</a> and <a href="https://github.com/zverok">Victor Shepelev</a> for their response and support and I am very grateful to the <a href="http://sciruby.com/">Ruby Science Foundation</a> for this golden opportunity.</p>

<p>I thank my fellow GSoC participants <a href="https://github.com/athityakumar">Athitya Kumar</a> and <a href="https://github.com/prasunanand">Prasun Anand</a> for their support and discussions on various topics.</p>

<p>Thanks to Google for conducting <a href="https://summerofcode.withgoogle.com">Google Summer of Code</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2017 : Support to Import & Export of more formats]]></title>
    <link href="http://sciruby.com/blog/2017/08/29/gsoc-2017-support-to-import-export-of-more-formats/"/>
    <updated>2017-08-29T17:16:00+05:30</updated>
    <id>http://sciruby.com/blog/2017/08/29/gsoc-2017-support-to-import-export-of-more-formats</id>
    <content type="html"><![CDATA[<h2>Introduction</h2>

<blockquote><p>&#8220;Hello friend. Hello friend? That&#8217;s lame.&#8221; - S01E01 (Pilot), Mr.Robot</p></blockquote>

<p>My name is Athitya Kumar, and I&#8217;m a 4th year undergrad from IIT Kharagpur, India. I
was selected as a GSoC 2017 student developer by Ruby Science Foundation for project daru-io.</p>

<p><a href="https://github.com/athityakumar/daru-io">Daru-IO</a> is a plugin-gem to
<a href="https://github.com/SciRuby/daru">Daru</a> gem, that extends support for many Import and Export
methods of <code>Daru::DataFrame</code>. This gem is intended to help Rubyists who are into Data Analysis
or Web Development, by serving as a general purpose conversion library.</p>

<p>Through this summer, I worked on adding support for various Importers and Exporters
while also porting some existing modules. Feel free to find a comprehensive set
of useful links in
<a href="https://athityakumar.github.io/blog/posts/GSoC_2017_-_Final_Work_Submission/">Final Work Submission</a>
and <a href="https://github.com/athityakumar/daru-io/blob/master/README.md">README</a>. Before proceeding any
further, you might also be interested in checking out a sample showcase of
<a href="https://daru-examples-io-view-rails.herokuapp.com/">Rails example</a> and
<a href="https://github.com/Shekharrajak/daru_examples_io_view_rails">the code</a> making it work.</p>

<h2>Mark Anthony&#8217;s Speech (ft. daru)</h2>

<blockquote><p>&#8220;Rubyists, Data Analysts and Web Developers, lend me your ears;</p>

<p>I come to write about my GSoC project, not to earn praise for it.&#8221;</p></blockquote>

<p>For the uninitiated, Google Summer of Code (GSoC) 2017 is a 3-month program that
focuses on introducing selected students to open-source software development.
To know more about GSoC, feel free to click
<a href="https://summerofcode.withgoogle.com/about/">here</a>.</p>

<p><a href="https://github.com/SciRuby/daru">daru</a> is a Ruby gem that stands for Data Analysis in RUby. My
<a href="https://drive.google.com/file/d/0B4shBmKvdinIZUNqcGwtWDZtb1NMMHg3SG51SFRqNlVqZkIw/">initial proposal</a>
was to make daru easier to integrate with Ruby web frameworks through better import-export features
(<a href="https://github.com/athityakumar/daru-io">daru-io</a>) and visualization methods
(<a href="https://github.com/Shekharrajak/daru-view">daru-view</a>). However, as both
<a href="https://github.com/Shekharrajak">Shekhar</a> and I
were selected for the same proposal, we split this amongst ourselves : daru-io was allocated to me
and daru-view was allocated to <a href="https://github.com/Shekharrajak">Shekhar</a>.</p>

<h2></h2>

<blockquote><p>&#8220;The open-source contributions that people do, live after them;</p>

<p>But their private contributions, are oft interred with their bones.&#8221;</p></blockquote>

<p>This is one of the reasons why I (and all open-source developers) are enthusiastic
about open-source. In open-source, one&#8217;s work can be re-used in other projects
in accordance with the listed LICENSE and attribution, compared to the restrictions
and risk of Intellectual Property Right claims in private work.</p>

<h2></h2>

<blockquote><p>&#8220;So be it. The noble Pythonistas and R developers;</p>

<p>Might not have chosen to try daru yet.&#8221;</p></blockquote>

<p>It is quite understandable that Pythonistas and R developers feel that their corresponding
languages have sufficient tools for Data Analysis. So, why would they switch to Ruby and
start using daru?</p>

<h2></h2>

<blockquote><p>&#8220;If it were so, it may have been a grievous fault;</p>

<p>Give daru a try, with daru-io and daru-view.&#8221;</p></blockquote>

<p>First of all, I don&#8217;t mean any offense when I say &#8220;grievous fault&#8221;. But please, do give
Ruby and daru family a try, with an open mind.</p>

<p>Voila - the daru family has two new additions, namely
<a href="https://github.com/athityakumar/daru-io">daru-io</a> and
<a href="https://github.com/Shekharrajak/daru-view">daru-view</a>. Ruby is a language
which is extensively used in Web Development with multiple frameworks such as Rails, Sinatra,
Nanoc, Jekyll, etc. With such a background, it only makes sense for daru to have daru-io and
daru-view as separate plugins, thus making the daru family easily integrable with Ruby web
frameworks.</p>

<h2></h2>

<blockquote><p>&#8220;Here, for attention of Rubyists and the rest–</p>

<p>For Pandas is an honourable library;</p>

<p>So are they all, all honourable libraries and languages–</p>

<p>Come I to speak about daru-io&#8217;s inception.&#8221;</p></blockquote>

<p>Sure, the alternatives in other languages like Python, R and Hadoop are also good data analysis
tools. But, how readily can they be integrated into any web application? R &amp; Hadoop don&#8217;t have a
battle-tested web framework yet, and are usually pipelined into the back-end of any application
to perform any analysis. I&#8217;m no one to judge such pipelines, but I feel that pipelines are
hackish workarounds rather than being a clean way of integrating.</p>

<p>Meanwhile, though Python too has its own set of web frameworks (like Django, Flask and more),
Pandas doesn&#8217;t quite work out-of-the-box with these frameworks and requires the web developer
to write lines and lines of code to integrate Pandas with parsing libraries and plotting
libraries.</p>

<h2></h2>

<blockquote><p>&#8220;daru-io is a ruby gem, and open-sourced to all of us;</p>

<p>But some might think it was an ambitious idea;</p>

<p>And they are all honourable men.&#8221;</p></blockquote>

<p>As described above, daru-io is open-sourced under the MIT License with attribution to
myself and Ruby Science Foundation. Being a ruby gem, daru-io follows the best practices
mentioned in the Rubygems guides and is all geared up with a v0.1.0 release.</p>

<p>Disclaimer - By &#8220;men&#8221;, I&#8217;m not stereotyping &#8220;them&#8221; to be all male, but I&#8217;m just merely
retaining the resemblence to the original speech of Mark Anthony.</p>

<h2></h2>

<blockquote><p>&#8220;daru-io helps convert data in many formats to Daru::DataFrame;</p>

<p>Whose methods can be used to analyze huge amounts of data.</p>

<p>Does this in daru-io seem ambitious?&#8221;</p></blockquote>

<p><a href="https://github.com/SciRuby/daru">Daru</a> has done a great job of encapsulating the two main
structures of Data Analysis - DataFrames and Vectors - with a ton of functionalities that are
growing day by day. But obviously, the huge amounts of data aren&#8217;t going to be manually fed into
the DataFrames right?</p>

<p>One part of <a href="https://github.com/athityakumar/daru-io">daru-io</a> is the battalion of Importers that
ship along with it. Importers are used to read from a file / Ruby instance, and create DataFrame(s).
These are the Importers being supported by v0.1.0 of daru-io :</p>

<ul>
<li>General file formats : CSV, Excel (xls and xlsx), HTML, JSON, Plaintext.</li>
<li>Special file formats : Avro, RData, RDS.</li>
<li>Database related : ActiveRecord, Mongo, Redis, SQLite, DBI.</li>
</ul>


<p>For more specific information about the Importers, please have a look at the
<a href="https://github.com/athityakumar/daru-io/blob/master/README.md#table-of-contents">README</a>
and <a href="http://www.rubydoc.info/github/athityakumar/daru-io/master/Daru/IO/Importers/">YARD Docs</a>.</p>

<p>Let&#8217;s take a simple example of the JSON Importer, to import from GitHub&#8217;s GraphQL API response. By
default, the API response is paginated and 30 repositories are listed in the url :
<code>https://api.github.com/users/#{username}/repos</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;daru/io/importers/json&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">dataframe</span> <span class="o">=</span> <span class="sx">%w[athityakumar zverok v0dro lokeshh]</span><span class="o">.</span><span class="n">map</span> <span class="k">do</span> <span class="o">|</span><span class="n">username</span><span class="o">|</span>
</span><span class='line'>  <span class="no">Daru</span><span class="o">::</span><span class="no">DataFrame</span><span class="o">.</span><span class="n">read_json</span><span class="p">(</span>
</span><span class='line'>    <span class="s2">&quot;https://api.github.com/users/</span><span class="si">#{</span><span class="n">username</span><span class="si">}</span><span class="s2">/repos&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="ss">RepositoryName</span><span class="p">:</span> <span class="s1">&#39;$..full_name&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="ss">Stars</span><span class="p">:</span> <span class="s1">&#39;$..stargazers_count&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="ss">Size</span><span class="p">:</span> <span class="s1">&#39;$..size&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="ss">Forks</span><span class="p">:</span> <span class="s1">&#39;$..forks_count&#39;</span>
</span><span class='line'>  <span class="p">)</span>
</span><span class='line'><span class="k">end</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="ss">:concat</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#=&gt; #&lt;Daru::DataFrame(120x4)&gt;</span>
</span><span class='line'><span class="c1">#      Repository   Stars   Size   Forks</span>
</span><span class='line'><span class="c1">#   0  athityakum       0      6       0</span>
</span><span class='line'><span class="c1">#   1  athityakum       0    212       0</span>
</span><span class='line'><span class="c1">#   2  athityakum       0    112       0</span>
</span><span class='line'><span class="c1">#  ...    ...          ...   ...     ...</span>
</span></code></pre></td></tr></table></div></figure>


<h2></h2>

<blockquote><p>&#8220;When working with a team of Pythonistas and R developers;</p>

<p>daru-io helps convert Daru::DataFrame to multiple formats.</p>

<p>Does this in daru-io seem ambitious?</p></blockquote>

<p>The second part of <a href="https://github.com/athityakumar/daru-io">daru-io</a> is the collection of Exporters
that ship with it. Exporters are used to write the data in a DataFrame, to a file / database. These
are the Exporters being supported by v0.1.0 of daru-io :</p>

<ul>
<li>General file formats : CSV, Excel (xls), JSON.</li>
<li>Special file formats : Avro, RData, RDS.</li>
<li>Database related : SQL.</li>
</ul>


<p>For more specific information about the Exporters, please have a look at the
<a href="https://github.com/athityakumar/daru-io/blob/master/README.md#table-of-contents">README</a>
and <a href="http://www.rubydoc.info/github/athityakumar/daru-io/master/Daru/IO/Exporters/">YARD Docs</a>.</p>

<p>Let&#8217;s take a simple example of the RDS Exporter. Say, your best friend is a R developer who&#8217;d like
to analyze a <code>Daru::DataFrame</code> that you have obtained, and perform further analysis. You don&#8217;t want
to break your friendship, and your friend is skeptical of learning Ruby. No issues, simply use the RDS
Exporter to export your <code>Daru::DataFrame</code> into a .rds file, which can be easily loaded by your friend
in R.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;daru/io/exporters/rds&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">dataframe</span> <span class="c1">#! Say, the DataFrame is obtained from the above JSON Importer example</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#=&gt; #&lt;Daru::DataFrame(120x4)&gt;</span>
</span><span class='line'><span class="c1">#      Repository   Stars   Size   Forks</span>
</span><span class='line'><span class="c1">#   0  athityakum       0      6       0</span>
</span><span class='line'><span class="c1">#   1  athityakum       0    212       0</span>
</span><span class='line'><span class="c1">#   2  athityakum       0    112       0</span>
</span><span class='line'><span class="c1">#  ...    ...          ...   ...     ...</span>
</span><span class='line'>
</span><span class='line'><span class="n">dataframe</span><span class="o">.</span><span class="n">write_rds</span><span class="p">(</span><span class="s1">&#39;github_api.rds&#39;</span><span class="p">,</span> <span class="s1">&#39;github.api.dataframe&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<h2></h2>

<blockquote><p>&#8220;You all did see that in the repository&#8217;s README;</p>

<p>Codeclimate presented a 4.0 GPA;</p>

<p>Code and tests were humbly cleaned;</p>

<p>with help of rubocop, rspec, rubocop-rspec and saharspec.</p>

<p>Ambition shouldn&#8217;t have been made of humble stuff.</p>

<p>Yet some might think it is an ambitious idea;</p>

<p>And sure, they are all honourable men.&#8221;</p></blockquote>

<p>Thanks to guidance from my mentors
<a href="https://github.com/zverok">Victor Shepelev</a>, <a href="https://github.com/v0dro">Sameer Deshmukh</a>
and <a href="https://github.com/lokeshh">Lokesh Sharma</a>, I&#8217;ve come to know about quite a lot
of Ruby tools that could be used to keep the codebase sane and clean.</p>

<ul>
<li><a href="https://github.com/bbatsov/rubocop">rubocop</a> : A Ruby static code analyzer, which enforces
specified Ruby style guidelines.</li>
<li><a href="https://github.com/rspec/rspec">rspec</a> : A unit-testing framework, which makes sure that codes
of block are doing what they&#8217;re logically supposed to do.</li>
<li><a href="https://github.com/backus/rubocop-rspec">rubocop-rspec</a> : A plugin gem to rubocop, that extends
rspec-related rules.</li>
<li><a href="https://github.com/zverok/saharspec">saharspec</a> : A gem with a
<a href="https://github.com/zverok/saharspec/blob/master/README.md#saharspec-specs-dry-as-sahara">punny name</a>, that extends a few features to rspec-its that are more readable. For example, <code>its_call</code>.</li>
</ul>


<h2></h2>

<blockquote><p>&#8220;I speak not to disapprove of what other libraries do;</p>

<p>But here I am to speak what I do know.</p>

<p>Give daru-io a try and y&#8217;all will love it, not without cause:</p>

<p>Does anything withhold you then, from using daru-io?&#8221;</p></blockquote>

<p>I really mean it, when I discretely specify &#8220;I speak not to disapprove of what other libraries do&#8221;.
In the world of open-source, there should never be hate among developers regarding languages,
or libraries. Developers definitely have their (strong) opinions and preferences, and it&#8217;s
understandable that difference in opinion do arise. But, as long as there&#8217;s mutual respect for
each other&#8217;s opinion and choice, all is well.</p>

<h2></h2>

<blockquote><p>&#8220;O Ruby community! Thou should definitely try out daru-io,</p>

<p>With daru and daru-view. Bear with me;</p>

<p>My heart is thankful to the community of Ruby Science Foundation,</p>

<p>And I must pause till I write another blog post.&#8221;</p></blockquote>

<p>If you&#8217;ve read all the way till down here, I feel that you&#8217;d be interested in trying out the
daru family, after having seen the impressive demonstration of Importers &amp; Exporters above, and
the Rails example (<a href="https://daru-examples-io-view-rails.herokuapp.com/">Website</a> |
<a href="https://github.com/Shekharrajak/daru_examples_io_view_rails">Code</a>). I&#8217;m very thankful to mentors
<a href="https://github.com/zverok">Victor Shepelev</a>, <a href="https://github.com/v0dro">Sameer Deshmukh</a>
and <a href="https://github.com/lokeshh">Lokesh Sharma</a> for their timely Pull Request reviews and open
discussions regarding features. Daru-IO would not have been possible without them and the active
community of Ruby Science Foundation, who provided their useful feedback(s) whenever they could.
The community has been very supportive overall, and hence I&#8217;d definitely be interested to involve
with SciRuby via more open-source projects.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2016: Adding Categorical Data Support]]></title>
    <link href="http://sciruby.com/blog/2016/11/24/gsoc-2016-adding-categorical-data-support/"/>
    <updated>2016-11-24T23:24:00+05:30</updated>
    <id>http://sciruby.com/blog/2016/11/24/gsoc-2016-adding-categorical-data-support</id>
    <content type="html"><![CDATA[<p>Support for categorical data is important for any data analysis
tool. This summer I implemented categorical data capabilities for:</p>

<ul>
<li>Convenient and efficient data wrangling for categorical data in <a href="https://github.com/v0dro/daru">Daru</a></li>
<li>Visualization of categorical data</li>
<li>Multiple linear regression and generalized linear models (GLM) with categorical variables in <a href="https://github.com/SciRuby/statsample">Statsample</a> and <a href="https://github.com/SciRuby/statsample-glm">Statsample-GLM</a></li>
</ul>


<p>Lets talk about each of them in detail.</p>

<h4>Analyzing catgorical data with Daru</h4>

<p>Categorical data is now readily recognized by
<a href="https://github.com/v0dro/daru">Daru</a> and Daru has all the necessary
procedures for dealing with it.</p>

<p>To analyze categorical variable, simply turn the numerical vector to categorical and you are ready to go.</p>

<p>We will use, for demonstration purposes, animal shelter data taken
from the <a href="https://www.kaggle.com/c/shelter-animal-outcomes">Kaggle Competition</a>. It is
stored in <code>shelter_data</code>.</p>

<p><img src="http://i65.tinypic.com/xeliqs.png" alt="" /></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># Tell Daru which variables are categorical</span>
</span><span class='line'><span class="n">shelter_data</span><span class="o">.</span><span class="n">to_category</span> <span class="s1">&#39;OutcomeType&#39;</span><span class="p">,</span> <span class="s1">&#39;AnimalType&#39;</span><span class="p">,</span> <span class="s1">&#39;SexuponOutcome&#39;</span><span class="p">,</span> <span class="s1">&#39;Breed&#39;</span><span class="p">,</span> <span class="s1">&#39;Color&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Or quantize a numerical variable to categorical</span>
</span><span class='line'><span class="n">shelter_data</span><span class="o">[</span><span class="s1">&#39;AgeuponOutcome&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">shelter_data</span><span class="o">[</span><span class="s1">&#39;AgeuponOutcome(Weeks)&#39;</span><span class="o">].</span><span class="n">cut</span> <span class="o">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">52</span><span class="p">,</span> <span class="mi">260</span><span class="p">,</span> <span class="mi">1500</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>    <span class="ss">labels</span><span class="p">:</span> <span class="o">[</span><span class="ss">:less_than_week</span><span class="p">,</span> <span class="ss">:less_than_month</span><span class="p">,</span> <span class="ss">:less_than_year</span><span class="p">,</span> <span class="ss">:one_to_five_years</span><span class="p">,</span> <span class="ss">:more_than__five_years</span><span class="o">]</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Do your operations on categorical data</span>
</span><span class='line'><span class="n">shelter_data</span><span class="o">[</span><span class="s1">&#39;AgeuponOutcome&#39;</span><span class="o">].</span><span class="n">frequencies</span><span class="o">.</span><span class="n">sort</span> <span class="ss">ascending</span><span class="p">:</span> <span class="kp">false</span>
</span></code></pre></td></tr></table></div></figure>


<p><img src="http://i67.tinypic.com/w1u3vs.png" alt="" /></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">small</span><span class="o">[</span><span class="s1">&#39;Breed&#39;</span><span class="o">].</span><span class="n">categories</span><span class="o">.</span><span class="n">size</span>
</span><span class='line'><span class="c1">#=&gt; 1380</span>
</span><span class='line'><span class="c1"># Merge infrequent categories to make data analysis easy</span>
</span><span class='line'><span class="n">other_cats</span> <span class="o">=</span> <span class="n">shelter_data</span><span class="o">[</span><span class="s1">&#39;Breed&#39;</span><span class="o">].</span><span class="n">categories</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">shelter_data</span><span class="o">[</span><span class="s1">&#39;Breed&#39;</span><span class="o">].</span><span class="n">count</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">10</span> <span class="p">}</span>
</span><span class='line'><span class="n">other_cats_hash</span> <span class="o">=</span> <span class="n">other_cats</span><span class="o">.</span><span class="n">zip</span><span class="p">(</span><span class="o">[</span><span class="s1">&#39;other&#39;</span><span class="o">]*</span><span class="n">other_cats</span><span class="o">.</span><span class="n">size</span><span class="p">)</span><span class="o">.</span><span class="n">to_h</span>
</span><span class='line'><span class="n">shelter_data</span><span class="o">[</span><span class="s1">&#39;Breed&#39;</span><span class="o">].</span><span class="n">rename_categories</span> <span class="n">other_cats_hash</span>
</span><span class='line'><span class="n">shelter_data</span><span class="o">[</span><span class="s1">&#39;Breed&#39;</span><span class="o">].</span><span class="n">frequencies</span>
</span><span class='line'><span class="c1"># View the data</span>
</span><span class='line'><span class="n">small</span><span class="o">[</span><span class="s1">&#39;Breed&#39;</span><span class="o">].</span><span class="n">frequencies</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="ss">ascending</span><span class="p">:</span> <span class="kp">false</span><span class="p">)</span><span class="o">.</span><span class="n">head</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p><img src="http://i64.tinypic.com/25rcu8m.png" alt="" /></p>

<p>Please refer to <a href="http://lokeshh.github.io/blog/2016/06/21/categorical-data/">this blog post</a> to know more.</p>

<h4>Visualizing categorical data</h4>

<p>With the help of <a href="https://github.com/SciRuby/nyaplot">Nyaplot</a>, <a href="https://github.com/SciRuby/gnuplotrb">GnuplotRB</a> and <a href="https://github.com/topfunky/gruff">Gruff</a>, Daru now provides ability to visualize categorical data as it does with numerical data.</p>

<p>To plot a vector with Nyaplot one needs to call the function <code>#plot</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># dv is a caetgorical vector</span>
</span><span class='line'><span class="n">dv</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">Vector</span><span class="o">.</span><span class="n">new</span> <span class="o">[</span><span class="s1">&#39;III&#39;</span><span class="o">]*</span><span class="mi">10</span> <span class="o">+</span> <span class="o">[</span><span class="s1">&#39;II&#39;</span><span class="o">]*</span><span class="mi">5</span> <span class="o">+</span> <span class="o">[</span><span class="s1">&#39;I&#39;</span><span class="o">]*</span><span class="mi">5</span><span class="p">,</span> <span class="ss">type</span><span class="p">:</span> <span class="ss">:category</span><span class="p">,</span> <span class="ss">categories</span><span class="p">:</span> <span class="o">[</span><span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;II&#39;</span><span class="p">,</span> <span class="s1">&#39;III&#39;</span><span class="o">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">dv</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="ss">type</span><span class="p">:</span> <span class="ss">:bar</span><span class="p">,</span> <span class="nb">method</span><span class="p">:</span> <span class="ss">:fraction</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="p">,</span> <span class="n">d</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">x_label</span> <span class="s1">&#39;Categories&#39;</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">y_label</span> <span class="s1">&#39;Fraction&#39;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p><img src="http://i64.tinypic.com/2s6onsw.png" alt="" /></p>

<p>Given a dataframe, one can plot the scatter plot such that the points
color, shape and size can be varied acording to a categorical
variable.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># df is a dataframe with categorical variable :c</span>
</span><span class='line'><span class="n">df</span> <span class="o">=</span> <span class="no">Daru</span><span class="o">::</span><span class="no">DataFrame</span><span class="o">.</span><span class="n">new</span><span class="p">({</span>
</span><span class='line'>  <span class="ss">a</span><span class="p">:</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">23</span><span class="p">,</span> <span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">b</span><span class="p">:</span> <span class="o">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="o">-</span><span class="mi">6</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">c</span><span class="p">:</span> <span class="o">[</span><span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;II&#39;</span><span class="p">,</span> <span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;III&#39;</span><span class="p">,</span> <span class="s1">&#39;I&#39;</span><span class="p">,</span> <span class="s1">&#39;III&#39;</span><span class="p">,</span> <span class="s1">&#39;II&#39;</span><span class="o">]</span>
</span><span class='line'>  <span class="p">})</span>
</span><span class='line'><span class="n">df</span><span class="o">.</span><span class="n">to_category</span> <span class="ss">:c</span>
</span><span class='line'>
</span><span class='line'><span class="n">df</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="ss">type</span><span class="p">:</span> <span class="ss">:scatter</span><span class="p">,</span> <span class="ss">x</span><span class="p">:</span> <span class="ss">:a</span><span class="p">,</span> <span class="ss">y</span><span class="p">:</span> <span class="ss">:b</span><span class="p">,</span> <span class="ss">categorized</span><span class="p">:</span> <span class="p">{</span><span class="ss">by</span><span class="p">:</span> <span class="ss">:c</span><span class="p">,</span> <span class="nb">method</span><span class="p">:</span> <span class="ss">:color</span><span class="p">})</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="p">,</span> <span class="n">d</span><span class="o">|</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">xrange</span> <span class="o">[-</span><span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="o">]</span>
</span><span class='line'>  <span class="nb">p</span><span class="o">.</span><span class="n">yrange</span> <span class="o">[-</span><span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="o">]</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p><img src="http://i64.tinypic.com/2mcfx28.png" alt="" /></p>

<p>In a similar manner Gnuplot and Gruff also support plotting of categorical variables.</p>

<p>An additional work I did was to add Gruff with Daru. Now one can plot
vectors and dataframes also using Gruff.</p>

<p>See more notebooks on visualizing categorical data with Daru
<a href="http://nbviewer.jupyter.org/github/SciRuby/sciruby-notebooks/tree/master/Data%20Analysis/Plotting/">here</a>.</p>

<h4>Regression with categorical data</h4>

<p>Now categorical data is supported in multiple linear regression and
generalized linear models (GLM) in
<a href="https://github.com/SciRuby/statsample">Statsample</a> and
<a href="https://github.com/SciRuby/statsample-glm">Statsample-GLM</a>.</p>

<p>A new formula language (like that used in R or
<a href="https://github.com/pydata/patsy">Patsy</a>) has been introduced to ease
the task of specifying regressions.</p>

<p>Now there&#8217;s no need to manually create a dataframe for regression.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;statsample-glm&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">formula</span> <span class="o">=</span> <span class="s1">&#39;OutcomeType_Adoption~AnimalType+Breed+AgeuponOutcome(Weeks)+Color+SexuponOutcome&#39;</span>
</span><span class='line'><span class="n">glm_adoption</span> <span class="o">=</span> <span class="no">Statsample</span><span class="o">::</span><span class="no">GLM</span><span class="o">::</span><span class="no">Regression</span><span class="o">.</span><span class="n">new</span> <span class="n">formula</span><span class="p">,</span> <span class="n">train</span><span class="p">,</span> <span class="ss">:logistic</span>
</span><span class='line'><span class="n">glm_adoption</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">coefficients</span> <span class="ss">:hash</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#=&gt; {:AnimalType_Cat=&gt;0.8376443692275163, :&quot;Breed_Pit Bull Mix&quot;=&gt;0.28200753488859803, :&quot;Breed_German Shepherd Mix&quot;=&gt;1.0518504638731023, :&quot;Breed_Chihuahua Shorthair Mix&quot;=&gt;1.1960242033878856, :&quot;Breed_Labrador Retriever Mix&quot;=&gt;0.445803000000512, :&quot;Breed_Domestic Longhair Mix&quot;=&gt;1.898703165797653, :&quot;Breed_Siamese Mix&quot;=&gt;1.5248210169271197, :&quot;Breed_Domestic Medium Hair Mix&quot;=&gt;-0.19504965010288533, :Breed_other=&gt;0.7895601504638325, :&quot;Color_Blue/White&quot;=&gt;0.3748263925801828, :Color_Tan=&gt;0.11356334165122918, :&quot;Color_Black/Tan&quot;=&gt;-2.6507089126322114, :&quot;Color_Blue Tabby&quot;=&gt;0.5234717706465536, :&quot;Color_Brown Tabby&quot;=&gt;0.9046099720184905, :Color_White=&gt;0.07739310267363662, :Color_Black=&gt;0.859906249787038, :Color_Brown=&gt;-0.003740755055106689, :&quot;Color_Orange Tabby/White&quot;=&gt;0.2336674067343927, :&quot;Color_Black/White&quot;=&gt;0.22564205490196415, :&quot;Color_Brown Brindle/White&quot;=&gt;-0.6744314269278774, :&quot;Color_Orange Tabby&quot;=&gt;2.063785952843677, :&quot;Color_Chocolate/White&quot;=&gt;0.6417921901449108, :Color_Blue=&gt;-2.1969040091451704, :Color_Calico=&gt;-0.08386525532631824, :&quot;Color_Brown/Black&quot;=&gt;0.35936722899161305, :Color_Tricolor=&gt;-0.11440457799048752, :&quot;Color_White/Black&quot;=&gt;-2.3593561796090383, :Color_Tortie=&gt;-0.4325130799770577, :&quot;Color_Tan/White&quot;=&gt;0.09637439333330515, :&quot;Color_Brown Tabby/White&quot;=&gt;0.12304448360566177, :&quot;Color_White/Brown&quot;=&gt;0.5867441296328475, :Color_other=&gt;0.08821407092892847, :&quot;SexuponOutcome_Spayed Female&quot;=&gt;0.32626712478395975, :&quot;SexuponOutcome_Intact Male&quot;=&gt;-3.971505056680895, :&quot;SexuponOutcome_Intact Female&quot;=&gt;-3.619095491410668, :SexuponOutcome_Unknown=&gt;-102.73807712615843, :&quot;AgeuponOutcome(Weeks)&quot;=&gt;-0.006959545305620043}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Additionally, through the work of <a href="https://github.com/agisga">Alexej Grossmann</a>,
one can also predict on new data using the model.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">predict</span> <span class="o">=</span> <span class="n">glm_adoption</span><span class="o">.</span><span class="n">predict</span> <span class="nb">test</span>
</span><span class='line'><span class="n">predict</span><span class="o">.</span><span class="n">map!</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="o">.</span><span class="mi">5</span> <span class="o">?</span> <span class="mi">0</span> <span class="p">:</span> <span class="mi">1</span> <span class="p">}</span>
</span><span class='line'><span class="n">predict</span><span class="o">.</span><span class="n">head</span> <span class="mi">5</span>
</span></code></pre></td></tr></table></div></figure>


<p><img src="http://i67.tinypic.com/r1af7p.png" alt="" /></p>

<p>This, I believe, makes Statsample-GLM very convenient to use.</p>

<p>See <a href="http://nbviewer.jupyter.org/github/SciRuby/sciruby-notebooks/blob/master/Data%20Analysis/Categorical%20Data/examples/%5BExample%5D%20Formula%20language%20in%20Statsample-GLM.ipynb">this</a> for a complete example.</p>

<h4>Other</h4>

<p>In addition to the aforementioned, there are some other considerable changes:</p>

<ul>
<li>Improving overall structure of indexing in Daru and adding more capabilities. See <a href="http://nbviewer.jupyter.org/github/SciRuby/sciruby-notebooks/blob/master/Data%20Analysis/Categorical%20Data/Indexing%20in%20Vector.ipynb">this</a> and <a href="http://nbviewer.jupyter.org/github/SciRuby/sciruby-notebooks/blob/master/Data%20Analysis/Categorical%20Data/Indexing%20in%20DataFrame.ipynb">this</a>.</li>
<li><code>CategoricalIndex</code> to handle the case when index column is a categorical data. <a href="http://lokeshh.github.io/blog/2016/06/14/categorical-index/">More about it here.</a></li>
<li>Improving missing value API in Daru. <a href="http://lokeshh.github.io/blog/2016/08/18/improve-missing-values-api-in-daru/">Read more about it here.</a></li>
<li>Configuring guard to enable automatic testing. <a href="https://github.com/v0dro/daru/blob/master/CONTRIBUTING.md#testing">More info here.</a></li>
</ul>


<h4>Documentation</h4>

<p><a href="http://lokeshh.github.io/blog/2016/06/21/categorical-data/">You can read about all my work in detail here.</a>. <a href="https://summerofcode.withgoogle.com/archive/2016/projects/5356167010189312/">Additionally, my project page can be found here.</a></p>

<p>I hope with these additions one will be able to see data more clearly with Daru.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2016: SpiceRub::KernelPool and Kernels]]></title>
    <link href="http://sciruby.com/blog/2016/11/24/spicerub-kernelpool-and-kernels/"/>
    <updated>2016-11-24T23:02:35+05:30</updated>
    <id>http://sciruby.com/blog/2016/11/24/spicerub-kernelpool-and-kernels</id>
    <content type="html"><![CDATA[<p>So this post comes rather late, but I&#8217;d still like to talk about what I did in the first week, and a little into the second week.
Firstly, thanks to a pull request offered by my GSoC mentor John (<a href="https://github.com/mohawkjohn">@mohawkjohn</a>), I now have rake tasks set up properly in the repository and rake seems to be working.</p>

<p>There are installation instructions in the <a href="https://github.com/sciruby/spice_rub/blob/master/README.rdoc">readme</a> and there are already some sample Kernel files in
the spec folder to try out various routines on. Apart from cloning the repository, one additional thing you will need to do is <a href="https://naif.jpl.nasa.gov/naif/toolkit_C.html">download the SPICE toolkit</a>. You may want to keep the entire compressed file for later, but you&#8217;ll only need the <code>cspice.a</code> file in the <code>lib/</code> subdirectory. After this follow the instructions in the <a href="https://github.com/sciruby/spice_rub/blob/master/README.rdoc">readme</a> and you should be good to go. (Be sure to run <code>bundle install</code> to install any dependencies that you don&#8217;t already have.)</p>

<p>After you&#8217;re done compiling and installing, run <code>rake pry</code> in the gem root directory.</p>

<p>If you remember, almost any useful task involving the SPICE Toolkit is preceded by loading data through kernel files. The relevant routine to do this is called <code>furnsh_c()</code> , and the most direct way to access it through Ruby is by calling the function <code>SpiceRub::Native.furnsh</code>. (However, this is not recommended because SpiceRub has a specific Ruby class unifying all the kernel related methods, and also because SPICE maintains its own internal variables for both tracking loaded kernel files and unloading them.)</p>

<p>Below is a crude dependency sequence:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">KernelPool</span><span class="o">.</span><span class="n">load</span> <span class="o">-&gt;</span>  <span class="no">SpiceRub</span><span class="o">::</span><span class="no">Native</span><span class="o">.</span><span class="n">furnsh</span> <span class="o">-&gt;</span> <span class="n">furnsh_c</span>
</span><span class='line'>
</span><span class='line'><span class="no">Ruby</span> <span class="no">Interface</span>            <span class="o">-&gt;</span>  <span class="n">C</span> <span class="no">Accessor</span>              <span class="o">-&gt;</span> <span class="no">External</span> <span class="n">library</span>
</span><span class='line'>
</span><span class='line'><span class="no">Ruby</span>                      <span class="o">-&gt;</span>  <span class="no">Native</span> <span class="no">Ruby</span><span class="o">-</span><span class="n">C</span> <span class="no">API</span>       <span class="o">-&gt;</span> <span class="no">Native</span> <span class="mi">3</span><span class="n">rd</span> <span class="no">Party</span> <span class="n">C</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>That&#8217;s the basic design of the wrapper, so here are a few simple examples on using the Kernel API. <code>=&gt;</code> denotes the interpreted output of pry.</p>

<p>First of all, the main KernelPool class is a singleton class, that means it can only be instantiated with the <code>#instance</code> method and the usual <code>#new</code> is private.
Any subsequent calls to <code>#instance</code> will produce the same object.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">kernel_pool</span> <span class="o">=</span> <span class="no">SpiceRub</span><span class="o">::</span><span class="no">KernelPool</span><span class="o">.</span><span class="n">instance</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::KernelPool:0x00000002db3218&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="n">rogue_kernel_pool</span> <span class="o">=</span> <span class="no">SpiceRub</span><span class="o">::</span><span class="no">KernelPool</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="ss">NoMethodError</span><span class="p">:</span> <span class="kp">private</span> <span class="nb">method</span> <span class="sb">`new&#39; called for SpiceRub::KernelPool:Class</span>
</span><span class='line'><span class="sb">from (pry):2:in `</span><span class="n">__pry__</span><span class="err">&#39;</span>
</span><span class='line'>
</span><span class='line'><span class="n">rogue_kernel_pool</span> <span class="o">=</span> <span class="no">SpiceRub</span><span class="o">::</span><span class="no">KernelPool</span><span class="o">.</span><span class="n">instance</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::KernelPool:0x00000002db3218&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="n">rogue_kernel_pool</span> <span class="o">==</span> <span class="n">kernel_pool</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">true</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>This is to make sure there is only one KernelPool state being maintained at a time. Now we have a bunch of kernel files in the <code>spec/data/kernels</code> folder which we&#8217;ll use for this example. There is an accessor attribute called <code>@path</code> which can be used to point to a particular folder.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="s1">&#39;spec/data/kernels&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>From here on it&#8217;s required that you&#8217;re running pry or irb from the gem root folder in order for the paths to match in these examples.</p>

<p>Now let&#8217;s load a couple of kernel files, you can type <code>system("ls", kernel_pool.path)</code> into your console to get a list of all the test kernels available in that folder. The KernelPool object has a <code>#load</code> method to load kernel files. If the variable path is set, then you only need to enter the file name, otherwise the entire path needs to be provided. An integer denoting the index of the kernel in the pool is returned if the load is successful.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="s2">&quot;naif0011.tls&quot;</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">0</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note that this is the same as providing the full relative path of <code>spec/data/kernels/naif0011.tls</code> when the <code>path</code>  variable is not set or nil.</p>

<p>Let&#8217;s load two more files:-</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="s2">&quot;moon_pa_de421_1900-2050.bpc&quot;</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">1</span>
</span><span class='line'>
</span><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="s2">&quot;de405_1960_2020.bsp&quot;</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">2</span>
</span><span class='line'>
</span><span class='line'><span class="n">kernel_pool</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::KernelPool:0x00000002db3218</span>
</span><span class='line'> <span class="vi">@path</span><span class="o">=</span><span class="s2">&quot;spec/data/kernels&quot;</span><span class="p">,</span>
</span><span class='line'> <span class="vi">@pool</span><span class="o">=</span>
</span><span class='line'>  <span class="o">[</span><span class="c1">#&lt;SpiceRub::KernelPool::SpiceKernel:0x0000000270fab0 @loaded=true, @path_to=&quot;spec/data/kernels/naif0011.tls&quot;&gt;,</span>
</span><span class='line'>   <span class="c1">#&lt;SpiceRub::KernelPool::SpiceKernel:0x000000026bd698 @loaded=true, @path_to=&quot;spec/data/kernels/moon_pa_de421_1900-2050.bpc&quot;&gt;,</span>
</span><span class='line'>   <span class="c1">#&lt;SpiceRub::KernelPool::SpiceKernel:0x000000024ce698 @loaded=true, @path_to=&quot;spec/data/kernels/de405_1960_2020.bsp&quot;&gt;]&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>So now if you try to view the <code>@pool</code> member of <code>kernel_pool</code>, you&#8217;ll find three SpiceKernel objects with <code>@loaded=true</code> and their respective file paths.
There isn&#8217;t much to do with a <code>SpiceKernel</code> object except unload it, or check its state. Note that you can only load kernel files into a <code>KernelPool</code> object and unload them via the <code>SpiceKernel</code> object.</p>

<p>You can access the kernel pool by calling the <code>#[]</code> operator and using the index that was returned on load:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">kernel_pool</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::KernelPool::SpiceKernel:0x0000000270fab0 @loaded=true, @path_to=&quot;spec/data/kernels/naif0011.tls&quot;&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">count</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">3</span>
</span><span class='line'>
</span><span class='line'><span class="n">kernel_pool</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="n">unload!</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'>
</span><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">count</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">2</span>
</span></code></pre></td></tr></table></div></figure>


<p>So here we unload the first kernel and note that the count drops to 2. If you look up <code>kernel_pool[0]</code>, you&#8217;ll find that the kernel is still present &mdash; but its <code>@loaded</code> variable has been set to false, which means that it has been removed from the CSPICE internal kernel pool.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">kernel_pool</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::KernelPool::SpiceKernel:0x0000000270fab0 @loaded=false, @path_to=&quot;spec/data/kernels/naif0011.tls&quot;&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>To unload all kernels simultaneously and delete the kernel pool, use <code>#clear!</code></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">clear!</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'>
</span><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">empty?</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">true</span>
</span><span class='line'>
</span><span class='line'><span class="n">kernel_pool</span><span class="o">.</span><span class="n">pool</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[]</span>
</span></code></pre></td></tr></table></div></figure>


<p>And that about wraps up this blog post on basic kernel handling. Since we know how to load data but not use it yet, I&#8217;ll cover that and the various kernel types in the next blog post. Thank you for reading.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2016 : A Look at SpiceRub::Body]]></title>
    <link href="http://sciruby.com/blog/2016/11/24/gsoc-2016-a-look-at-spicerub-body/"/>
    <updated>2016-11-24T22:53:00+05:30</updated>
    <id>http://sciruby.com/blog/2016/11/24/gsoc-2016-a-look-at-spicerub-body</id>
    <content type="html"><![CDATA[<p>One of the main goals of this project was to make the ephemerides
functions easily available to an end user. Ephemerides basically
refers to an object in space whose motion is being tracked and
observed. SPICE required you to provide the following parameters to
observe a body in space.</p>

<ul>
<li><code>Target</code>: The body of interest</li>
<li><code>Frame</code>: A rotational frame of reference (Default is J2000 [Not to be confused with the J2000 epoch])</li>
<li><code>Observer</code>: An observing body whose viewpoint is used to chart the vector</li>
<li><code>Epoch</code> : An epoch in Ephemeris Time</li>
</ul>


<p>SPICE has an integer-key convention for the kind of bodies that it
has support for. Each body can be referenced via a string or an
integer id. While there isn&#8217;t an actual strict range for integer ID
classification, it is mentioned <a href="https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html">here</a> and can be summed up
in the following <code>if</code> and <code>elsif</code> clauses. (In Ruby constant strings
are better off as symbols, so the constructor takes either an integer
ID of a string symbol)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">if</span> <span class="n">body_id</span> <span class="o">&gt;</span> <span class="mi">2000000</span>
</span><span class='line'>    <span class="ss">:asteroid</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="n">body_id</span> <span class="o">&gt;</span> <span class="mi">1000000</span>
</span><span class='line'>    <span class="ss">:comet</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="n">body_id</span> <span class="o">&gt;</span> <span class="mi">1000</span>
</span><span class='line'>    <span class="ss">:body</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="n">body_id</span> <span class="o">&gt;</span> <span class="mi">10</span>
</span><span class='line'>    <span class="n">body_id</span> <span class="o">%</span> <span class="mi">100</span> <span class="o">==</span> <span class="mi">99</span> <span class="o">?</span>
</span><span class='line'>      <span class="ss">:planet</span> <span class="p">:</span> <span class="ss">:satellite</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="n">body_id</span> <span class="o">==</span> <span class="mi">10</span>
</span><span class='line'>    <span class="ss">:star</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="n">body_id</span> <span class="o">&gt;</span> <span class="mi">0</span>
</span><span class='line'>    <span class="ss">:barycenter</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="n">body_id</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1000</span>
</span><span class='line'>    <span class="ss">:spacecraft</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="n">body_id</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">100000</span>
</span><span class='line'>    <span class="ss">:instrument</span>
</span><span class='line'>  <span class="k">else</span>
</span><span class='line'>    <span class="ss">:spacecraft</span>
</span></code></pre></td></tr></table></div></figure>


<p>It was very tempting to involve inheritance and extend a base Body
class onto these potential classes, but I simply did not see the need
for it at this point. The way it is at the moment, the <code>Body</code> object
has a reader attribute type that stores some metadata about the body
for the user&#8217;s convenience. Perhaps as coverage of SPICE improves,
this minor thing can be changed later on.</p>

<p>To create a Body object, you instantiate with either a body name or a
body id. Certain bodies such as instruments will require additional
kernels to be loaded. To proceed seamlessly, load a leap seconds
kernel, a planetary constants kernel, and an ephemeris kernel. (All
avaialable in <code>spec/data/kernels</code>)</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Body</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">399</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::Body:0x00000002769da8</span>
</span><span class='line'>     <span class="vi">@code</span><span class="o">=</span><span class="mi">399</span><span class="p">,</span>
</span><span class='line'>     <span class="vi">@frame</span><span class="o">=</span><span class="ss">:J2000</span><span class="p">,</span>
</span><span class='line'>     <span class="vi">@name</span><span class="o">=</span><span class="ss">:earth</span><span class="p">,</span>
</span><span class='line'>     <span class="vi">@type</span><span class="o">=</span><span class="ss">:planet</span><span class="o">&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Body</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:earth</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::Body:0x000000026c73c8</span>
</span><span class='line'>   <span class="vi">@code</span><span class="o">=</span><span class="mi">399</span><span class="p">,</span>
</span><span class='line'>   <span class="vi">@frame</span><span class="o">=</span><span class="ss">:J2000</span><span class="p">,</span>
</span><span class='line'>   <span class="vi">@name</span><span class="o">=</span><span class="ss">:earth</span><span class="p">,</span>
</span><span class='line'>   <span class="vi">@type</span><span class="o">=</span><span class="ss">:planet</span><span class="o">&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Body</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:moon</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::Body:0x0000000214ac88</span>
</span><span class='line'>   <span class="vi">@code</span><span class="o">=</span><span class="mi">301</span><span class="p">,</span>
</span><span class='line'>   <span class="vi">@frame</span><span class="o">=</span><span class="ss">:J2000</span><span class="p">,</span>
</span><span class='line'>   <span class="vi">@name</span><span class="o">=</span><span class="ss">:moon</span><span class="p">,</span>
</span><span class='line'>   <span class="vi">@type</span><span class="o">=</span><span class="ss">:satellite</span><span class="o">&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>399</code> and <code>:earth</code> map to the same body in SPICE data. The frame of
reference can also be specified as a named parameter during
instantiation to set a custom default frame for that particular
object.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Body</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">399</span><span class="p">,</span> <span class="ss">frame</span><span class="p">:</span> <span class="no">IAU_EARTH</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::Body:0x000000020b1df8</span>
</span><span class='line'>     <span class="vi">@code</span><span class="o">=</span><span class="mi">399</span><span class="p">,</span>
</span><span class='line'>     <span class="vi">@frame</span><span class="o">=</span><span class="ss">:IAU_EARTH</span><span class="p">,</span>
</span><span class='line'>     <span class="vi">@name</span><span class="o">=</span><span class="ss">:earth</span><span class="p">,</span>
</span><span class='line'>     <span class="vi">@type</span><span class="o">=</span><span class="ss">:planet</span><span class="o">&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>In SPICE, a <code>state</code> is a 6 length column vector that stores position
and velocity in 3D cartesian co-ordinates</p>

<p>As a base case, let&#8217;s find out the the position of the Earth with
respect to itself.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">earth</span><span class="o">.</span><span class="n">position_at</span><span class="p">(</span><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> <span class="ss">observer</span><span class="p">:</span> <span class="n">earth</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span>
</span><span class='line'><span class="o">[</span>
</span><span class='line'>  <span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>   <span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>   <span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>The origin as seen from itself is still the origin, so this makes
sense. The methods <code>#velocity_at</code> and <code>#state_at</code> take an identical
set of parameters. While there is a bit of redundancy going on,
splitting them makes the API more elegant, but the basic relationship
between these three vectors is the following :-</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">state</span> <span class="o">=</span> <span class="o">[</span>
</span><span class='line'>          <span class="n">position</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span><span class="n">position</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">,</span><span class="n">position</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>          <span class="n">velocity</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span><span class="n">velocity</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">,</span><span class="n">velocity</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span>
</span><span class='line'>        <span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>One thing to note is that state/velocity/position vectors will always
be returned as an <code>NMatrix</code> object, SciRuby&#8217;s numerical matrix core,
to allow for calculations via the NMatrix API.</p>

<p>As an example that is used in the code, one line can turn a position
vector into distance from origin (here using Euclidean distance):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="n">position</span> <span class="o">=</span> <span class="n">earth</span><span class="o">.</span><span class="n">position_at</span><span class="p">(</span><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> <span class="ss">observer</span><span class="p">:</span> <span class="n">observer</span><span class="p">)</span>
</span><span class='line'>  <span class="no">Math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span> <span class="p">(</span><span class="n">position</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span><span class="o">.</span><span class="n">sum</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>As a simple imprecise experiment, let&#8217;s find out how the speed of
light can be &#8220;estimated&#8221; up with this data.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">distance</span> <span class="o">=</span> <span class="n">moon</span><span class="o">.</span><span class="n">distance_from</span><span class="p">(</span><span class="n">earth</span><span class="p">,</span> <span class="n">now</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">367441</span><span class="o">.</span><span class="mo">0260</span><span class="mi">814745</span>
</span><span class='line'>
</span><span class='line'><span class="n">time</span> <span class="o">=</span> <span class="n">moon</span><span class="o">.</span><span class="n">light_time_from</span><span class="p">(</span><span class="n">earth</span><span class="p">,</span> <span class="n">now</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">1</span><span class="o">.</span><span class="mi">2256513340354764</span>
</span><span class='line'>
</span><span class='line'><span class="n">distance</span> <span class="o">/</span> <span class="n">time</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">299792</span><span class="o">.</span><span class="mi">458</span>
</span></code></pre></td></tr></table></div></figure>


<p>The unit of distance here is kilometers, so the speed of light by this
measurement is about pretty close to the textbook figure of 3e+8 m/s.</p>

<p>There is also a function to check if a list of bodies are within a
radial proximity from an observing body. We already calculated the
distance of the moon to be about 367,000 km. The function
<code>within_proximity</code> returns a list of all bodies that are within the
specified radial distance from the calling body object.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1">#assuming venus and mercury are instantiated</span>
</span><span class='line'>
</span><span class='line'><span class="n">earth</span><span class="o">.</span><span class="n">within_proximity</span><span class="p">(</span><span class="o">[</span><span class="n">moon</span><span class="p">,</span> <span class="n">venus</span><span class="p">,</span> <span class="n">mercury</span><span class="o">]</span><span class="p">,</span> <span class="mi">400000</span><span class="p">,</span> <span class="n">now</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span><span class="c1">#&lt;SpiceRub::Body:0x0000000191c4f8</span>
</span><span class='line'>  <span class="vi">@code</span><span class="o">=</span><span class="mi">301</span><span class="p">,</span>
</span><span class='line'>  <span class="vi">@frame</span><span class="o">=</span><span class="ss">:J2000</span><span class="p">,</span>
</span><span class='line'>  <span class="vi">@name</span><span class="o">=</span><span class="ss">:moon</span><span class="p">,</span>
</span><span class='line'>  <span class="vi">@type</span><span class="o">=</span><span class="ss">:satellite</span><span class="o">&gt;]</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now that we&#8217;ve come to the end of the functionality, I would like to
mention that there is another named argument <code>aberration_correction</code>
which is basically an error reduction method to provide a more
accurate result than the default observation. The default <code>:none</code>
option for aberration correction basically provides the geometric
observations without any corrections for reception or transmission of
photons. For a list of various aberration correction methods
available, have a look at the documentation for <a href="ftp://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkpos_c.html">spkpos_c</a> to
find out if you need an aberration correction on SPICE data.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">d1</span> <span class="o">=</span> <span class="n">moon</span><span class="o">.</span><span class="n">distance_from</span><span class="p">(</span><span class="n">earth</span><span class="p">,</span> <span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> <span class="ss">aberration_correction</span><span class="p">:</span> <span class="ss">:none</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">369111</span><span class="o">.</span><span class="mo">055033313</span><span class="mi">8</span>
</span><span class='line'><span class="n">d2</span> <span class="o">=</span> <span class="n">moon</span><span class="o">.</span><span class="n">distance_from</span><span class="p">(</span><span class="n">earth</span><span class="p">,</span> <span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> <span class="ss">aberration_correction</span><span class="p">:</span> <span class="ss">:LT</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">369146</span><span class="o">.</span><span class="mi">60640691273</span>
</span><span class='line'>
</span><span class='line'><span class="n">d2</span> <span class="o">-</span> <span class="n">d1</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">35</span><span class="o">.</span><span class="mi">55137359892251</span>
</span></code></pre></td></tr></table></div></figure>


<p>If you want to look at it another way, no aberration correction would
give you the textbook response of rigid geometry, while introducing an
aberration correction would give you a somewhat more realistic output
accounting for the errors that do happen when these observations are
made.</p>

<p>Finally, if you need to generate a continuous time series for a body,
then <code>SpiceRub::Time</code> has two functions to aid in that:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">linear_time_series</span><span class="p">(</span><span class="n">now</span><span class="p">,</span> <span class="n">now</span> <span class="o">+</span> <span class="mi">86400</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000001fe8b60 @et=525180780.18277323&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000001fe8a20 @et=525209580.18277323&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000001fe88b8 @et=525238380.18277323&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000001fe8750 @et=525267180.18277323&gt;</span>
</span><span class='line'>   <span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>In this case, I took a start time and an end time that was one day
after and requested 4 linearly spaced epochs. This is basically an
interface to <code>NMatrix.linspace</code>.</p>

<p>The other function requires you to input a start time and an end time
and a step size that keeps getting added to the start time till the
end time is reached. As a contrived example, we&#8217;ll take two epochs,
five days apart and ask for a step size of a day, expecting six
elements.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">time_series</span><span class="p">(</span><span class="n">now</span><span class="p">,</span> <span class="n">now</span> <span class="o">+</span> <span class="mi">5</span> <span class="o">*</span> <span class="mi">86400</span><span class="p">,</span> <span class="ss">step</span><span class="p">:</span> <span class="mi">86400</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000001646580 @et=525180780.18277323&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000002f315b8 @et=525267180.18277323&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000002f31590 @et=525353580.18277323&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000002f31568 @et=525439980.18277323&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000002f31540 @et=525526380.18277323&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000002f31518 @et=525612780.18277323&gt;</span>
</span><span class='line'>   <span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>And that&#8217;s it for this blog post. I would appreciate any feedback
regarding this as I&#8217;ve been juggling the design back and forth very
frequently. There is large potential of expansion of the <code>Body</code> class,
particularly creating new classes as when different Bobdy objects
would have a corresponding function. (For example, the function
<code>getfov_c</code> which returns the field of view of an instrument could be
an instance function attached to the <code>Instrument</code> subclass of <code>Body</code>,
but this is just potential expansions in the future.)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2016 : A Look at SpiceRub::Time]]></title>
    <link href="http://sciruby.com/blog/2016/11/24/gsoc-2016-a-look-at-spicerub-time/"/>
    <updated>2016-11-24T22:52:00+05:30</updated>
    <id>http://sciruby.com/blog/2016/11/24/gsoc-2016-a-look-at-spicerub-time</id>
    <content type="html"><![CDATA[<p>Many popular programming languages these days ship with powerful Time
classes/interfaces to make the inevitable task of dealing with
time-related computations a more DRY experience. Humans like their
time representations to be stringy concatenations of various numbers
and alphabets that enable a large variety of date and time formats to
mean the same thing and still make instant sense to the human eye. It
was the creation of time zones that made our convenient 24-hour clocks
stay the way they are without experiencing day and night at the same
&#8220;time&#8221; across the globe. So now <code>00:00 A.M. UTC</code> is <code>5:30 A.M. IST</code>
for me, and the world remains sane.</p>

<p>But what happens when you accept the fact that you&#8217;re just a speck of
micro-dust adjusting time relatively for an only slightly bigger speck
of dust floating in the universe? Twenty-four hours in a day and thus we reset
after 2300, but consider: how would a resident of Venus know
when tea-time is on Venus if he had an Earth wristwatch that reset
after twenty-four hours? Barely a tenth of Venus&#8217; day is complete in that time!
(If you know anybody intent on relocating to Mars, do not gift them a
clock or watch.)</p>

<p>So a decimal floating point representation must be the answer for
uniformity. Time zones can be dealt with; we&#8217;ll just pick a convenient
point in time and count the seconds from there onwards so that the
location on Earth doesn&#8217;t matter henceforth. It&#8217;ll drive humans insane
with the arithmetic but machines will work just fine with this. This
sort of a time system is called epoch time.</p>

<p>And so the internal time of most UNIX machines is the number of
seconds after midnight on <code>Thursday, 1 January 1970 UTC</code>. (And this
very convention is going to open a can of worms by
<a href="https://en.wikipedia.org/wiki/Year_2038_problem">2038</a> if there is even a small set of critical machines
that haven&#8217;t moved on from 32-bit architectures.)</p>

<p>But we&#8217;re still not okay universally. Try going on an infinite journey
to space and you&#8217;ll find that counting seconds leads to some
inconsistencies with your local time when you try to synchronize with
Earth. How can the number of seconds after January 1970 be different
in any case? Well, your MacBook Pro has not been adjusted for
&#8230; relativity! Gravity bends light and thus the perception of
time. There&#8217;s a lot more mass, and thus a lot more gravitatonal fields
in neighborhoods away from Earth. The exact details of how this works
is beyond the scope of this blog post.</p>

<p>If the past few paragraphs were incessant and seemingly irrelevant,
they were there to drive home the point that Earth time simply will
not do when we step out of the ghetto to see what&#8217;s happening. But
astronomy&#8217;s been around for way longer, and astrophysicists came
forth with a time system adjusted for the relativity effects of the
solar system, called Barycentric Dynamical Time, or <em>TDB</em>. Like our
machines, it counts the seconds after a certain known reference time
point, except that it adjusts for relativity and can become a standard
for astronomical time.</p>

<p>There are many similar time scales like this, but SPICE has chosen to
use TDB as the standard for most of their design. Within the SPICE
API, TDB is the same as <em>Ephemeris Time</em> which is the main system used
to specify time points of astronomical bodies. Even though spacecrafts
have their clocks coordinated with UTC on Earth, you would require
that time in Ephemeris Time to be able to calculate their positions and
velocities using SPICE. <code>SpiceRub::Time</code> is built for this very purpose,
to revolve around a main attribute <code>@et</code> for Ephemeris Time and
provide many methods to convert to and from.</p>

<p>If you&#8217;d like to proceed with the examples, you&#8217;ll need a Leap Second
Kernel file to use <code>SpiceRub::Time</code>. This is a generic kernel, so you
can easily use <code>naif0011.tls</code> in <code>spec/data/kernels</code> of the repository
folder.</p>

<p>So Ephemeris Time is the number of seconds elapsed after <code>Noon, January 1, 2000, TDB</code>. This point in time is also known as the <code>J2000</code>
epoch. We find that out in an instant by using the <code>Time.parse</code>
function which is a wrapper function for SPICE&#8217;s <code>str2et_c</code> that
converts many formats of strings to <code>Ephemeris Time</code>. You can have a
look at the various string formats supported in its documentation
<a href="https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html">here</a></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&quot;12:00 Jan 1 2000 TDB&quot;</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::Time:0x0000000325b1f8 @et=0.0&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>So as a base case, using the reference epoch gives us 0 seconds as we would expect. Now would also be a good time to find out the discrepancy in <code>UTC</code> as well.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&quot;12:00 Jan 1 2000 UTC&quot;</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::Time:0x000000031c28e0 @et=64.18392728473108&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>So right away we know that UTC was 64-ish seconds off from TDB / ET at the time of the reference J2000 epoch. What would the difference be around right now?</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">now</span> <span class="o">=</span> <span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SpiceRub::Time:0x000000030bf8f8 @et=525173312.1827749&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="p">(</span><span class="n">now</span> <span class="o">-</span> <span class="n">now</span><span class="o">.</span><span class="n">to_utc</span><span class="p">)</span><span class="o">.</span><span class="n">to_f</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">68</span><span class="o">.</span><span class="mi">18277490139008</span>
</span></code></pre></td></tr></table></div></figure>


<p>Well, here&#8217;s a surprise, it&#8217;s 68.18 now. Before I explain why that is,
here is a brief overview of what the above code does:</p>

<p><code>Time.now</code> is a convenient way to specify your current UTC
timezone. It uses Ruby&#8217;s core <code>Time.now</code> method so this method is only
good if you&#8217;re working in UTC or Earth like Timezones. For a similar
purpose, the function <code>Time.from_time</code> let&#8217;s you create a SpiceRub
Time object from a Ruby Time object.</p>

<p>The <code>+/-</code> operators return a new Time object where the right operand
is added/subtracted to the left operand&#8217;s <code>@et</code> when it is a float or
integer. If a Time object is supplied , then it does the same with the
right operand&#8217;s ephemeris time instead. (Note that there really isn&#8217;t
a significant meaning to having a Time object whose @et is the
difference/sum of two other epochs, however you can increase a certain
epoch or decrease it by a constant offset of seconds)</p>

<p>In our case we used <code>#to_utc</code> to convert from ephemeris time to UTC,
and then the minus operator gave us a Time object that wasn&#8217;t really
an epoch, but a difference of two epochs, so using <code>#to_f</code> got us
exactly that.</p>

<p>It appears that UTC has changed by 4 seconds since 2000 with respect
to ephemeris time. This is actually the adjustment of &#8220;leap seconds&#8221;
that gets added to UTC to prevent it from falling too far behind other
time systems. (Humans really like to hack everything, don&#8217;t they?)</p>

<p>To verify this yourself, if you open up the kernel <code>naif0011.tls</code> in your
text editor and search for <code>DELTET/DELTA_AT</code>, you&#8217;ll find a list like
representation of the following sort :-</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">DELTET</span><span class="o">/</span><span class="no">DELTA_AT</span>        <span class="o">=</span> <span class="p">(</span> <span class="mi">10</span><span class="p">,</span>   <span class="err">@</span><span class="mi">1972</span><span class="o">-</span><span class="no">JAN</span><span class="o">-</span><span class="mi">1</span>
</span><span class='line'>                           <span class="o">.</span><span class="n">.</span><span class="p">,</span>   <span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'>                           <span class="mi">32</span><span class="p">,</span>   <span class="err">@</span><span class="mi">1999</span><span class="o">-</span><span class="no">JAN</span><span class="o">-</span><span class="mi">1</span>
</span><span class='line'>                           <span class="mi">33</span><span class="p">,</span>   <span class="err">@</span><span class="mi">2006</span><span class="o">-</span><span class="no">JAN</span><span class="o">-</span><span class="mi">1</span>
</span><span class='line'>                           <span class="mi">34</span><span class="p">,</span>   <span class="err">@</span><span class="mi">2009</span><span class="o">-</span><span class="no">JAN</span><span class="o">-</span><span class="mi">1</span>
</span><span class='line'>                           <span class="mi">35</span><span class="p">,</span>   <span class="err">@</span><span class="mi">2012</span><span class="o">-</span><span class="no">JUL</span><span class="o">-</span><span class="mi">1</span>
</span><span class='line'>                           <span class="mi">36</span><span class="p">,</span>   <span class="err">@</span><span class="mi">2015</span><span class="o">-</span><span class="no">JUL</span><span class="o">-</span><span class="mi">1</span> <span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here you can see that just before the year 2000, there were 32 leap
seconds added to UTC, and in 2015 when the last leap second was added,
there were 36. It&#8217;s an ongoing and indefinite process and so there
really is no way to account for leap second errors far in the future
for leap seconds that are yet to be added. As of now, the next
scheduled addition is in December, 2016.</p>

<p>Coming back to our Time object, let&#8217;s look at its basic
construction. One tricky task in the API was the option to specify
different epochs of reference in different time scales, like
International Atomic Time. As of now, <code>Time.new</code> requires that you
have kept your word of using the J2000 epoch and allows you to use a
named parameter <code>seconds:</code> for specifying the time scale. The use of
<code>scale</code> as a key was avoided as it sometimes is also used to refer to the
reference epoch used.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">epochs</span> <span class="o">=</span> <span class="o">[</span><span class="ss">:utc</span><span class="p">,</span> <span class="ss">:tdb</span><span class="p">,</span> <span class="ss">:tai</span><span class="o">].</span><span class="n">map</span>
</span><span class='line'>  <span class="p">{</span> <span class="o">|</span><span class="n">scale</span><span class="o">|</span> <span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="ss">seconds</span><span class="p">:</span> <span class="n">scale</span><span class="p">)</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span><span class="c1">#&lt;SpiceRub::Time:0x00000002756fc8 @et=64.18392728466942&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000002756eb0 @et=0&gt;,</span>
</span><span class='line'>    <span class="c1">#&lt;SpiceRub::Time:0x00000002756cf8 @et=32.18392727400827&gt;]</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>:tai</code> here refers to International Atomic Time. For a list of more
parameters and their keyword abbreviations, have a look at
<a href="https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unitim_c.html">this</a> SPICE documentation for the function that the
conversion is wrapped on top of.</p>

<p>But there is also a way to reference other epochs without doing the
manual conversions yourself, you can call the class method <code>Time.at</code>
to perform the same function as the constructor, with the option of a
different reference epoch. The resultant Time object will however have
its internal time referring to J2000.</p>

<p>A more readable way would involve step by step calculations, but that
would consume runtime resources everytime <code>Time.at</code> is called, so I&#8217;ve
basically pre-calculated the ephemeris times of the reference epochs
and subtracted them from the epoch.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">case</span> <span class="n">reference</span><span class="o">.</span><span class="n">downcase</span>
</span><span class='line'>  <span class="k">when</span> <span class="ss">:j2100</span>
</span><span class='line'>    <span class="kp">new</span><span class="p">(</span><span class="n">offset</span> <span class="o">+</span> <span class="mi">3155760000</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">seconds</span><span class="p">:</span> <span class="n">seconds</span><span class="p">)</span>
</span><span class='line'>  <span class="k">when</span> <span class="ss">:j2000</span><span class="p">,</span> <span class="ss">:et</span>
</span><span class='line'>    <span class="kp">new</span><span class="p">(</span><span class="n">offset</span><span class="p">,</span> <span class="ss">seconds</span><span class="p">:</span> <span class="n">seconds</span><span class="p">)</span>
</span><span class='line'>  <span class="k">when</span> <span class="ss">:j1950</span>
</span><span class='line'>    <span class="kp">new</span><span class="p">(</span><span class="n">offset</span> <span class="o">-</span> <span class="mi">1577880000</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">seconds</span><span class="p">:</span> <span class="n">seconds</span><span class="p">)</span>
</span><span class='line'>  <span class="k">when</span> <span class="ss">:j1900</span>
</span><span class='line'>    <span class="kp">new</span><span class="p">(</span><span class="n">offset</span> <span class="o">-</span> <span class="mi">3155760000</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">seconds</span><span class="p">:</span> <span class="n">seconds</span><span class="p">)</span>
</span><span class='line'>  <span class="k">when</span> <span class="ss">:gps</span>
</span><span class='line'>    <span class="kp">new</span><span class="p">(</span><span class="n">offset</span> <span class="o">-</span> <span class="mi">630763148</span><span class="o">.</span><span class="mi">8159368</span><span class="p">,</span> <span class="ss">seconds</span><span class="p">:</span> <span class="n">seconds</span><span class="p">)</span>
</span><span class='line'>  <span class="k">when</span> <span class="ss">:unix</span>
</span><span class='line'>    <span class="kp">new</span><span class="p">(</span><span class="n">offset</span> <span class="o">-</span> <span class="mi">946727958</span><span class="o">.</span><span class="mi">8160644</span><span class="p">,</span> <span class="ss">seconds</span><span class="p">:</span> <span class="n">seconds</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>To quickly verify the last one with the <code>#to_s</code> method:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">-</span><span class="mi">946727958</span><span class="o">.</span><span class="mi">8160644</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;Thu Jan 01 00:00:00 UTC 1970&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>It&#8217;s exactly the UNIX epoch! Let&#8217;s try out 1 day (86400 seconds) after
this epoch:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SpiceRub</span><span class="o">::</span><span class="no">Time</span><span class="o">.</span><span class="n">at</span><span class="p">(</span><span class="mi">86400</span><span class="p">,</span> <span class="ss">:unix</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;Thu Jan 01 23:59:59 UTC 1970&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Just a second short of heading into the next day, because we&#8217;ve added
86400 TDB seconds and converted the time into a UTC string.</p>

<p>There are some more functions provided to work in tandem with the
<code>Body</code> class that I&#8217;ll explain more about in the next blog post, but
this more or less covers the core of <code>SpiceRub:Time</code>. Till then,
thanks for reading.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2016: NMatrix and JRuby]]></title>
    <link href="http://sciruby.com/blog/2016/10/24/gsoc-2016-port-nmatrix-to-jruby/"/>
    <updated>2016-10-24T22:43:00+05:30</updated>
    <id>http://sciruby.com/blog/2016/10/24/gsoc-2016-port-nmatrix-to-jruby</id>
    <content type="html"><![CDATA[<h2>Introduction</h2>

<p>I worked on &#8220;Port NMatrix to JRuby&#8221; in the context of the Google
Summer of Code (GSoC) 2016 and I am pleased to announce that NMatrix
can now be used in JRuby.</p>

<p>With JRuby NMatrix, a linear algebra library, wraps <a href="http://commons.apache.org/proper/commons-math/">Apache Commons Math</a> for its most
basic functionalities. NMatrix supports dense matrices containing
either doubles or Ruby objects as the data type. The performance of JRuby
with Apache Commons Maths is quite satisfactory (see below for performance
comparisons) even without making use of JRuby threading capabilities.</p>

<p>I have also ported the <a href="https://github.com/agisga/mixed_models">mixed_models gem</a>, which
uses NMatrix heavily at its core, to JRuby. This gem allowed us
to test NMatrix-JRuby with real-life data.</p>

<p>This blog post summarizes my work on the project with SciRuby, and
reports the final status of the project.</p>

<p>The original GSoC proposal, plan and application can be found <a href="https://github.com/prasunanand/resume/blob/master/gsoc2016_application.md">here</a>. Until merging
is complete, commits are available <a href="https://github.com/prasunanand/nmatrix/commits/jruby_port">here</a>.</p>

<h2>Performance</h2>

<p>I have benchmarked some of the NMatrix functionalities. The following
plots compare the performance between NMatrix-JRuby, NMatrix-MRI, and
NMatrix-MRI using LAPACK/ATLAS libraries. (Note: MRI refers to the
reference implementation of Ruby, for those who are new.)</p>

<p>Notes:</p>

<ol>
<li>LAPACK and ATLAS aren&#8217;t involved in most element-wise operations, such as addition and subtraction.</li>
<li>NMatrix-MRI relies on LAPACK/ATLAS for calculating determinants and LU Decomposition (lud).</li>
</ol>


<p><img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/plots/add.png?raw=true" title="Fig. 3: Matrix Addition" alt="Alt Matrix Addition" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/plots/subt.png?raw=true" title="Fig. 4: Matrix Subtraction" alt="Alt Matrix Subtraction" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/plots/mult.png?raw=true" title="Fig. 5: Matrix Multiplication" alt="Alt Matrix Multiplication" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/plots/gamma.png?raw=true" title="Fig. 6: Gamma Operator" alt="Alt Gamma operator" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/plots/det.png?raw=true" title="Fig. 7: Determinant" alt="Alt Determinant" />
<img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/plots/lud.png?raw=true" title="Fig. 8: LU Facorization" alt="Alt LU Facorization" /></p>

<h3>Result</h3>

<ol>
<li><p>For two-dimensional matrices, NMatrix-JRuby is currently slower than NMatrix-MRI for matrix multiplication and matrix decomposition functionalities (calculating determinant and factoring a matrix). NMatrix-JRuby is faster than NMatrix-MRI for other functionalities of a two-dimensional matrix &mdash; like addition, subtraction, trigonometric operations, etc.</p></li>
<li><p>NMatrix-JRuby is a clear winner when we are working with matrices of arbitrary dimensions.</p></li>
</ol>


<h2>Implementation</h2>

<h3>Storing <em>n</em>-dimensional matrices as one-dimensional arrays</h3>

<p>The major components of an <code>NMatrix</code> are shape, elements, dtype and
stype. When initialized, the dense type stores the elements as a one-dimensional
array; in the JRuby port, the <code>ArrayRealVector</code> class is used to store
the elements.</p>

<p><code>@s</code> stores elements, <code>@shape</code> stores the shape of the matrix, while
<code>@dtype</code> and <code>@stype</code> store the data type and storage type
respectively. Currently, I have nmatrix-jruby implemented only for
<code>:float64</code> (double) and Ruby <code>:object</code> data types.</p>

<p>NMatrix-MRI uses <code>struct</code> as a <code>type</code> to store <code>dim</code>, <code>shape</code>, <code>offset</code>, <code>count</code>, <code>src</code>
of an NMatrix. <code>ALLOC</code> and <code>xfree</code> are used to wrap the NMatrix attributes to C structs
and release the unrequired memory.</p>

<p><img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/nmatrix.png?raw=true" title="Fig. 1: NMatrix" alt="NMatrix" /></p>

<h3>Slicing and Rank</h3>

<p>Implementing slicing was the toughest part of NMatrix-JRuby
implementation. <code>NMatrix@s</code> stores the elements of a matrix as a
one-dimensional array. The elements along any dimension are accessed with the
help of the stride. <code>NMatrix#get_stride</code> calculates the stride with
the help of the dimension and shape and returns an Array.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">get_stride</span><span class="p">(</span><span class="n">nmatrix</span><span class="p">)</span>
</span><span class='line'>  <span class="n">stride</span> <span class="o">=</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
</span><span class='line'>  <span class="p">(</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">nmatrix</span><span class="o">.</span><span class="n">dim</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
</span><span class='line'>    <span class="n">stride</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">dim</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">j</span><span class="o">|</span>
</span><span class='line'>      <span class="n">stride</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">*=</span> <span class="n">nmatrix</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="n">j</span><span class="o">]</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">stride</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>NMatrix#[]</code> and <code>NMatrix#[]=</code> are thus able to read and write the
elements of a matrix. NMatrix#MRI uses the <code>@s</code> object which stores
the stride when the nmatrix is initialized.</p>

<p><code>NMatrix#[]</code> calls the <code>#xslice</code> operator which calls <code>#get_slice</code>
operator that use the stride to determine whether we are accessing a
single element or multiple elements. If there are multiple elements,
<code>#dense_storage_get</code> returns an NMatrix object with the elements along
the dimension.</p>

<p>NMatrix-MRI differs from NMatrix-JRuby implementation as it makes sure
that memory is properly utilized as the memory needs to be properly
garbage collected.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">xslice</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
</span><span class='line'>  <span class="n">result</span> <span class="o">=</span> <span class="kp">nil</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="nb">self</span><span class="o">.</span><span class="n">dim</span> <span class="o">&lt;</span> <span class="n">args</span><span class="o">.</span><span class="n">length</span>
</span><span class='line'>    <span class="k">raise</span><span class="p">(</span><span class="no">ArgumentError</span><span class="p">,</span><span class="s2">&quot;wrong number of arguments\</span>
</span><span class='line'><span class="s2">       (</span><span class="si">#{</span><span class="n">args</span><span class="si">}</span><span class="s2"> for </span><span class="si">#{</span><span class="n">effective_dim</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="k">else</span>
</span><span class='line'>    <span class="n">result</span> <span class="o">=</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="p">()</span>
</span><span class='line'>    <span class="n">slice</span> <span class="o">=</span> <span class="n">get_slice</span><span class="p">(</span><span class="vi">@dim</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="vi">@shape</span><span class="p">)</span>
</span><span class='line'>    <span class="n">stride</span> <span class="o">=</span> <span class="n">get_stride</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">slice</span><span class="o">[</span><span class="ss">:single</span><span class="o">]</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="vi">@dtype</span> <span class="o">==</span> <span class="ss">:object</span><span class="p">)</span>
</span><span class='line'>        <span class="n">result</span> <span class="o">=</span> <span class="vi">@s</span><span class="o">[</span><span class="n">dense_storage_get</span><span class="p">(</span><span class="n">slice</span><span class="p">,</span><span class="n">stride</span><span class="p">)</span><span class="o">]</span>
</span><span class='line'>      <span class="k">else</span>
</span><span class='line'>        <span class="n">s</span> <span class="o">=</span> <span class="vi">@s</span><span class="o">.</span><span class="n">toArray</span><span class="p">()</span><span class="o">.</span><span class="n">to_a</span>
</span><span class='line'>        <span class="n">result</span> <span class="o">=</span> <span class="vi">@s</span><span class="o">.</span><span class="n">getEntry</span><span class="p">(</span><span class="n">dense_storage_get</span><span class="p">(</span><span class="n">slice</span><span class="p">,</span><span class="n">stride</span><span class="p">))</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'>      <span class="n">result</span> <span class="o">=</span> <span class="n">dense_storage_get</span><span class="p">(</span><span class="n">slice</span><span class="p">,</span><span class="n">stride</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">result</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>NMatrix#[]=</code> calls the <code>#dense_storage_set</code> operator which calls
 <code>#get_slice</code> operator that use the stride to find out whether we are
 accessing a single element or multiple elements. If there are
 multiple elements <code>#set_slice</code> recursively sets the elements of the
 matrix then returns an NMatrix object with the elements along the
 dimension.</p>

<p>All the relevant code for slicing can be found <a href="https://github.com/prasunanand/nmatrix/blob/jruby_port/lib/nmatrix/jruby/slice.rb">here</a>.</p>

<h3>Enumerators</h3>

<p>NMatrix-MRI uses the C code for enumerating the elements of a
matrix. Just as with slicing, the NMatrix-JRuby uses pure Ruby code in
place of the C code. Currently, all the enumerators for dense matrices
with real data-type have been implemented and are properly
functional. Enumerators for objects have not yet been implemented.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">each_with_indices</span>
</span><span class='line'>  <span class="n">nmatrix</span> <span class="o">=</span> <span class="n">create_dummy_nmatrix</span>
</span><span class='line'>  <span class="n">stride</span> <span class="o">=</span> <span class="n">get_stride</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span>
</span><span class='line'>  <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span>
</span><span class='line'>  <span class="c1">#Create indices and initialize them to zero</span>
</span><span class='line'>  <span class="n">coords</span> <span class="o">=</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">dim</span><span class="p">){</span> <span class="mi">0</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">shape_copy</span> <span class="o">=</span>  <span class="nb">Array</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">dim</span><span class="p">)</span>
</span><span class='line'>  <span class="p">(</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">size</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">k</span><span class="o">|</span>
</span><span class='line'>    <span class="n">dense_storage_coords</span><span class="p">(</span><span class="n">nmatrix</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">coords</span><span class="p">,</span> <span class="n">stride</span><span class="p">,</span> <span class="n">offset</span><span class="p">)</span>
</span><span class='line'>    <span class="n">slice_index</span> <span class="o">=</span> <span class="n">dense_storage_pos</span><span class="p">(</span><span class="n">coords</span><span class="p">,</span><span class="n">stride</span><span class="p">)</span>
</span><span class='line'>    <span class="n">ary</span> <span class="o">=</span> <span class="nb">Array</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="vi">@dtype</span> <span class="o">==</span> <span class="ss">:object</span><span class="p">)</span>
</span><span class='line'>      <span class="n">ary</span> <span class="o">&lt;&lt;</span> <span class="nb">self</span><span class="o">.</span><span class="n">s</span><span class="o">[</span><span class="n">slice_index</span><span class="o">]</span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'>      <span class="n">ary</span> <span class="o">&lt;&lt;</span> <span class="nb">self</span><span class="o">.</span><span class="n">s</span><span class="o">.</span><span class="n">toArray</span><span class="o">.</span><span class="n">to_a</span><span class="o">[</span><span class="n">slice_index</span><span class="o">]</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>    <span class="p">(</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">dim</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
</span><span class='line'>      <span class="n">ary</span> <span class="o">&lt;&lt;</span> <span class="n">coords</span><span class="o">[</span><span class="nb">p</span><span class="o">]</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># yield the array which now consists of the value and the indices</span>
</span><span class='line'>    <span class="k">yield</span><span class="p">(</span><span class="n">ary</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span> <span class="k">if</span> <span class="nb">block_given?</span>
</span><span class='line'>  <span class="n">nmatrix</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="vi">@s</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="n">nmatrix</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Two-Dimensional Matrices</h3>

<p>Linear algebra is mostly about two-dimensional matrices. In NMatrix,
when performing calculations in a two-dimensional matrix, a one-dimensional array
is converted to a two-dimensional matrix. A two-dimensional matrix is
stored in the JRuby implementation as a <code>BlockRealMatrix</code> or
<code>Array2DRowRealMatrix</code>. Each has its own advantages.</p>

<h4>Getting a 2D Matrix</h4>

<p><img src="https://github.com/prasunanand/gsoc_blog/blob/master/img/sciruby_blog/matrixGenerate.png?raw=true" title="Fig. 2: Getting a 2D-matrix" alt="Alt Getting a 2D-matrix" /></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MatrixGenerator</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">double</span><span class="o">[][]</span> <span class="nf">getMatrixDouble</span><span class="o">(</span><span class="kt">double</span><span class="o">[]</span> <span class="n">array</span><span class="o">,</span> <span class="kt">int</span> <span class="n">row</span><span class="o">,</span> <span class="kt">int</span> <span class="n">col</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>    <span class="kt">double</span><span class="o">[][]</span> <span class="n">matrix</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">double</span><span class="o">[</span><span class="n">row</span><span class="o">][</span><span class="n">col</span><span class="o">];</span>
</span><span class='line'>    <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">index</span><span class="o">=</span><span class="mi">0</span><span class="o">,</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span> <span class="o">;</span> <span class="n">i</span><span class="o">++){</span>
</span><span class='line'>        <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="o">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">col</span><span class="o">;</span> <span class="n">j</span><span class="o">++){</span>
</span><span class='line'>            <span class="n">matrix</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="n">j</span><span class="o">]=</span> <span class="n">array</span><span class="o">[</span><span class="n">index</span><span class="o">];</span>
</span><span class='line'>            <span class="n">index</span><span class="o">++;</span>
</span><span class='line'>        <span class="o">}</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">matrix</span><span class="o">;</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>Convert a 2D-matrix to 1D-array</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ArrayGenerator</span>
</span><span class='line'><span class="o">{</span>
</span><span class='line'>  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">double</span><span class="o">[]</span> <span class="nf">getArrayDouble</span><span class="o">(</span><span class="kt">double</span><span class="o">[][]</span> <span class="n">matrix</span><span class="o">,</span> <span class="kt">int</span> <span class="n">row</span><span class="o">,</span> <span class="kt">int</span> <span class="n">col</span><span class="o">)</span>
</span><span class='line'>  <span class="o">{</span>
</span><span class='line'>    <span class="kt">double</span><span class="o">[]</span> <span class="n">array</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">double</span><span class="o">[</span><span class="n">row</span> <span class="o">*</span> <span class="n">col</span><span class="o">];</span>
</span><span class='line'>    <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">index</span><span class="o">=</span><span class="mi">0</span><span class="o">,</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">row</span> <span class="o">;</span> <span class="n">i</span><span class="o">++){</span>
</span><span class='line'>        <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="o">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">col</span><span class="o">;</span> <span class="n">j</span><span class="o">++){</span>
</span><span class='line'>            <span class="n">array</span><span class="o">[</span><span class="n">index</span><span class="o">]</span> <span class="o">=</span> <span class="n">matrix</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="n">j</span><span class="o">];</span>
</span><span class='line'>            <span class="n">index</span><span class="o">++;</span>
</span><span class='line'>        <span class="o">}</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">array</span><span class="o">;</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h4>Why use a Java method instead of Ruby method?</h4>

<ol>
<li><p><em>Memory Usage and Garbage Collection:</em> A scientific library is memory intensive and hence, every step counts. The JRuby interpreter doesn&#8217;t need to dynamically guess the data type and uses less memory, typically around one-tenth of it. If the memory is properly utilized, when the GC kicks in, the GC has to clear less used memory space.</p></li>
<li><p><em>Speed:</em> Using java method greatly improves the speed &mdash; by around 1000 times, when compared to using the Ruby method.</p></li>
</ol>


<h2><strong>Operators</strong></h2>

<p>All the operators from NMatrix-MRI have been implemented except
modulus. The binary operators were easily implemented through Commons
Math API and Java Math API.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">+</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
</span><span class='line'>  <span class="n">result</span> <span class="o">=</span> <span class="n">create_dummy_nmatrix</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">NMatrix</span><span class="p">))</span>
</span><span class='line'>    <span class="c1">#check dimension</span>
</span><span class='line'>    <span class="k">raise</span><span class="p">(</span><span class="no">ShapeError</span><span class="p">,</span> <span class="s2">&quot;Cannot add matrices with different dimension&quot;</span><span class="p">)\</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="vi">@dim</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">dim</span><span class="p">)</span>
</span><span class='line'>    <span class="c1">#check shape</span>
</span><span class='line'>    <span class="p">(</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">dim</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
</span><span class='line'>      <span class="k">raise</span><span class="p">(</span><span class="no">ShapeError</span><span class="p">,</span> <span class="s2">&quot;Cannot add matrices with different shapes&quot;</span><span class="p">)</span> <span class="p">\</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="vi">@shape</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>    <span class="n">result</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="vi">@s</span><span class="o">.</span><span class="n">copy</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">s</span><span class="p">)</span>
</span><span class='line'>  <span class="k">else</span>
</span><span class='line'>    <span class="n">result</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="vi">@s</span><span class="o">.</span><span class="n">copy</span><span class="o">.</span><span class="n">mapAddToSelf</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">result</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Unary Operators (Trigonometric, Exponentiation and Log operators) have been implemented using <code>#mapToSelf</code> method that takes a <a href="https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/analysis/UnivariateFunction.html"><code>Univariate function</code></a> as an argument. <code>#mapToSelf</code> maps every element of ArrayRealVector object to the <code>Univariate function</code>, that is passed to it and returns <code>self</code> object.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">sin</span>
</span><span class='line'>  <span class="n">result</span> <span class="o">=</span> <span class="n">create_dummy_nmatrix</span>
</span><span class='line'>  <span class="n">result</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="vi">@s</span><span class="o">.</span><span class="n">copy</span><span class="o">.</span><span class="n">mapToSelf</span><span class="p">(</span><span class="no">Sin</span><span class="o">.</span><span class="n">new</span><span class="p">())</span>
</span><span class='line'>  <span class="n">result</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>NMatrix#method(arg) has been implemented using bivariate functions
provided by Commons Math API and Java Math API.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">gamma</span>
</span><span class='line'>  <span class="n">result</span> <span class="o">=</span> <span class="n">create_dummy_nmatrix</span>
</span><span class='line'>  <span class="n">result</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="no">ArrayRealVector</span><span class="o">.</span><span class="n">new</span> <span class="no">MathHelper</span><span class="o">.</span><span class="n">gamma</span><span class="p">(</span><span class="vi">@s</span><span class="o">.</span><span class="n">toArray</span><span class="p">)</span>
</span><span class='line'>  <span class="n">result</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kn">import</span> <span class="nn">org.apache.commons.math3.special.Gamma</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MathHelper</span><span class="o">{</span>
</span><span class='line'>  <span class="o">...</span>
</span><span class='line'>  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">double</span><span class="o">[]</span> <span class="nf">gamma</span><span class="o">(</span><span class="kt">double</span><span class="o">[]</span> <span class="n">arr</span><span class="o">){</span>
</span><span class='line'>    <span class="kt">double</span><span class="o">[]</span> <span class="n">result</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">double</span><span class="o">[</span><span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">];</span>
</span><span class='line'>    <span class="k">for</span><span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span><span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++){</span>
</span><span class='line'>      <span class="n">result</span><span class="o">[</span><span class="n">i</span><span class="o">]</span> <span class="o">=</span> <span class="n">Gamma</span><span class="o">.</span><span class="na">gamma</span><span class="o">(</span><span class="n">arr</span><span class="o">[</span><span class="n">i</span><span class="o">]);</span>
</span><span class='line'>    <span class="o">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">result</span><span class="o">;</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>  <span class="o">...</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Decomposition</h3>

<p>NMatrix-MRI relies on LAPACK and ATLAS for matrix decomposition and
solving functionalities. Apache Commons Math provides a different set
of API for decomposing a matrix and solving an equation. For example,
<code>#potrf</code> and other LAPACK specific functions have not been implemented
as they are not required at all.</p>

<p>Calculating determinant in NMatrix is tricky where a matrix is reduced
either to a lower or upper matrix and the diagonal elements of the
matrix are multiplied to get the result. Also, the correct sign of the
result (whether positive or negative) is taken into account while
calculating the determinant. However, NMatrix-JRuby uses Commons Math
API to calculate the determinant.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">det_exact</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="vi">@dim</span> <span class="o">!=</span> <span class="mi">2</span> <span class="o">||</span> <span class="vi">@shape</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="o">!=</span> <span class="vi">@shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>    <span class="k">raise</span><span class="p">(</span><span class="no">ShapeError</span><span class="p">,</span> <span class="s2">&quot;matrices must be square to have a determinant defined&quot;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">return</span> <span class="kp">nil</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="n">to_return</span> <span class="o">=</span> <span class="no">LUDecomposition</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">twoDMat</span><span class="p">)</span><span class="o">.</span><span class="n">getDeterminant</span><span class="p">()</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Given below is code that shows how Cholesky decomposition has been
implemented by using Commons Math API.</p>

<h4>Cholesky Decomposition</h4>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">def</span> <span class="nf">factorize_cholesky</span>
</span><span class='line'>    <span class="n">cholesky</span> <span class="o">=</span> <span class="no">CholeskyDecomposition</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">twoDMat</span><span class="p">)</span>
</span><span class='line'>    <span class="n">l</span> <span class="o">=</span> <span class="n">create_dummy_nmatrix</span>
</span><span class='line'>    <span class="n">twoDMat</span> <span class="o">=</span> <span class="n">cholesky</span><span class="o">.</span><span class="n">getL</span>
</span><span class='line'>    <span class="n">l</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="no">ArrayRealVector</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">ArrayGenerator</span><span class="o">.</span><span class="n">getArrayDouble</span><span class="p">\</span>
</span><span class='line'>        <span class="p">(</span><span class="n">twoDMat</span><span class="o">.</span><span class="n">getData</span><span class="p">,</span> <span class="vi">@shape</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span> <span class="vi">@shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">u</span> <span class="o">=</span> <span class="n">create_dummy_nmatrix</span>
</span><span class='line'>    <span class="n">twoDMat</span> <span class="o">=</span> <span class="n">cholesky</span><span class="o">.</span><span class="n">getLT</span>
</span><span class='line'>    <span class="n">u</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="no">ArrayRealVector</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">ArrayGenerator</span><span class="o">.</span><span class="n">getArrayDouble</span><span class="p">\</span>
</span><span class='line'>      <span class="p">(</span><span class="n">twoDMat</span><span class="o">.</span><span class="n">getData</span><span class="p">,</span> <span class="vi">@shape</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span> <span class="vi">@shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">))</span>
</span><span class='line'>    <span class="k">return</span> <span class="o">[</span><span class="n">u</span><span class="p">,</span><span class="n">l</span><span class="o">]</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Similarly, LU Decomposition and QR factorization have been implemented.</p>

<h4>LU Decomposition</h4>

<p><a href="https://github.com/prasunanand/nmatrix/blob/jruby_port/lib/nmatrix/jruby/math.rb#L365">Code</a></p>

<h4>QR Factorization</h4>

<p><a href="https://github.com/prasunanand/nmatrix/blob/jruby_port/lib/nmatrix/jruby/math.rb#L392">Code</a></p>

<h4><code>NMatrix#solve</code></h4>

<p>The solve method currently uses LU and Cholesky decomposition.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">def</span> <span class="nf">solve</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">opts</span> <span class="o">=</span> <span class="p">{})</span>
</span><span class='line'>    <span class="k">raise</span><span class="p">(</span><span class="no">ShapeError</span><span class="p">,</span> <span class="s2">&quot;Must be called on square matrix&quot;</span><span class="p">)\</span>
</span><span class='line'>       <span class="k">unless</span> <span class="nb">self</span><span class="o">.</span><span class="n">dim</span> <span class="o">==</span> <span class="mi">2</span> <span class="o">&amp;&amp;</span> <span class="nb">self</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="o">==</span> <span class="nb">self</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span>
</span><span class='line'>    <span class="k">raise</span><span class="p">(</span><span class="no">ShapeError</span><span class="p">,</span> <span class="s2">&quot;number of rows of b must equal number\</span>
</span><span class='line'><span class="s2">       of cols of self&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="nb">self</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="o">!=</span> <span class="n">b</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'>    <span class="k">raise</span><span class="p">(</span><span class="no">ArgumentError</span><span class="p">,</span> <span class="s2">&quot;only works with dense matrices&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="nb">self</span><span class="o">.</span><span class="n">stype</span> <span class="o">!=</span> <span class="ss">:dense</span>
</span><span class='line'>    <span class="k">raise</span><span class="p">(</span><span class="no">ArgumentError</span><span class="p">,</span> <span class="s2">&quot;only works for non-integer, non-object dtypes&quot;</span><span class="p">)\</span>
</span><span class='line'>       <span class="k">if</span> <span class="n">integer_dtype?</span> <span class="ow">or</span> <span class="n">object_dtype?</span> <span class="ow">or</span> <span class="n">b</span><span class="o">.</span><span class="n">integer_dtype?</span> <span class="ow">or</span> <span class="n">b</span><span class="o">.</span><span class="n">object_dtype?</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">opts</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">form</span><span class="p">:</span> <span class="ss">:general</span> <span class="p">}</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">opts</span><span class="p">)</span>
</span><span class='line'>    <span class="n">x</span>    <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">clone</span>
</span><span class='line'>    <span class="n">n</span>    <span class="o">=</span> <span class="nb">self</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'>    <span class="n">nrhs</span> <span class="o">=</span> <span class="n">b</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">nmatrix</span> <span class="o">=</span> <span class="n">create_dummy_nmatrix</span>
</span><span class='line'>    <span class="k">case</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:form</span><span class="o">]</span>
</span><span class='line'>    <span class="k">when</span> <span class="ss">:general</span><span class="p">,</span> <span class="ss">:upper_tri</span><span class="p">,</span> <span class="ss">:upper_triangular</span><span class="p">,</span> <span class="ss">:lower_tri</span><span class="p">,</span> <span class="ss">:lower_triangular</span>
</span><span class='line'>      <span class="c1">#LU solver</span>
</span><span class='line'>      <span class="n">solver</span> <span class="o">=</span> <span class="no">LUDecomposition</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">twoDMat</span><span class="p">)</span><span class="o">.</span><span class="n">getSolver</span>
</span><span class='line'>      <span class="n">nmatrix</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="n">solver</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">b</span><span class="o">.</span><span class="n">s</span><span class="p">)</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">nmatrix</span>
</span><span class='line'>    <span class="k">when</span> <span class="ss">:pos_def</span><span class="p">,</span> <span class="ss">:positive_definite</span>
</span><span class='line'>      <span class="n">solver</span> <span class="o">=</span> <span class="no">Choleskyecomposition</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="nb">self</span><span class="o">.</span><span class="n">twoDMat</span><span class="p">)</span><span class="o">.</span><span class="n">getSolver</span>
</span><span class='line'>      <span class="n">nmatrix</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="n">solver</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">b</span><span class="o">.</span><span class="n">s</span><span class="p">)</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">nmatrix</span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'>      <span class="k">raise</span><span class="p">(</span><span class="no">ArgumentError</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">opts</span><span class="o">[</span><span class="ss">:form</span><span class="o">]</span><span class="si">}</span><span class="s2"> is not a valid form option&quot;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h4><code>NMatrix#matrix_solve</code></h4>

<p>Suppose we need to solve a system of linear equations:</p>

<pre><code>                    AX = B
</code></pre>

<p>where A is an m×n matrix, B and X are n×p matrices, we need to solve this equation by iterating through B.</p>

<p>NMatrix-MRI implements this functionality using <code>NMatrix::BLAS::cblas_trsm</code> method. However, for NMatrix-JRuby,  <code>NMatrix#matrix_solve</code> is the analogous method used.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">def</span> <span class="nf">matrix_solve</span> <span class="n">rhs</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">rhs</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="o">&gt;</span> <span class="mi">1</span>
</span><span class='line'>      <span class="n">nmatrix</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span> <span class="ss">:copy</span>
</span><span class='line'>      <span class="n">nmatrix</span><span class="o">.</span><span class="n">shape</span> <span class="o">=</span> <span class="n">rhs</span><span class="o">.</span><span class="n">shape</span>
</span><span class='line'>      <span class="n">res</span> <span class="o">=</span> <span class="o">[]</span>
</span><span class='line'>      <span class="c1">#Solve a matrix and store the vectors in a matrix</span>
</span><span class='line'>      <span class="p">(</span><span class="mi">0</span><span class="o">.</span><span class="n">.</span><span class="o">.</span><span class="n">rhs</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
</span><span class='line'>        <span class="n">res</span> <span class="o">&lt;&lt;</span> <span class="nb">self</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">rhs</span><span class="o">.</span><span class="n">col</span><span class="p">(</span><span class="n">i</span><span class="p">))</span><span class="o">.</span><span class="n">s</span><span class="o">.</span><span class="n">toArray</span><span class="o">.</span><span class="n">to_a</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="c1">#res is in col major format</span>
</span><span class='line'>      <span class="n">result</span> <span class="o">=</span> <span class="no">ArrayGenerator</span><span class="o">.</span><span class="n">getArrayColMajorDouble</span> <span class="p">\</span>
</span><span class='line'>         <span class="n">res</span><span class="o">.</span><span class="n">to_java</span> <span class="ss">:double</span><span class="p">,</span> <span class="n">rhs</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span> <span class="n">rhs</span><span class="o">.</span><span class="n">shape</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span>
</span><span class='line'>      <span class="n">nmatrix</span><span class="o">.</span><span class="n">s</span> <span class="o">=</span> <span class="no">ArrayRealVector</span><span class="o">.</span><span class="n">new</span> <span class="n">result</span>
</span><span class='line'>
</span><span class='line'>      <span class="k">return</span> <span class="n">nmatrix</span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'>      <span class="k">return</span> <span class="nb">self</span><span class="o">.</span><span class="n">solve</span> <span class="n">rhs</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Currently, Hessenberg transformation for NMatrix-JRuby has not been implemented.</p>

<h3>Other dtypes</h3>

<p>I have tried implementing float dtypes using <code>FloatMatrix</code> class
provide by jblas.  jblas was used instead of Commons Math as the
latter uses <code>Field Elements</code> for Floats and it had some issues
with <code>Reflection</code> and <code>Type Erasure</code>.
However, using jblas resulted in errors due to precision.</p>

<h2>Code Organisation and Deployment</h2>

<p>To minimise conflict with the MRI codebase all the JRuby front end
code has been placed in the <code>/lib/nmatrix/jruby</code>
directory. <code>lib/nmatrix/nmatrix.rb</code> decides whether to load
<code>nmatrix.so</code> or <code>nmatrix_jruby.rb</code> after detecting the Ruby platform.</p>

<p>The added advantage is that the Ruby interpreter must not decide which
function to call at run-time. The impact on performance can be seen
when programs which intensively use NMatrix for linear algebraic
computations (<em>e.g.</em>, mixed_models) are run.</p>

<h2>Spec Report</h2>

<p>After the port; this is the final report that summarizes the number of tests that successfully pass:</p>

<h3>NMatrix</h3>

<table>
<thead>
<tr>
<th></th>
<th>Spec file</th>
<th align="center">Total Tests</th>
<th align="center">Success</th>
<th align="center">Failure</th>
<th align="center">Pending</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>00_nmatrix_spec</td>
<td align="center">188</td>
<td align="center">139</td>
<td align="center">43</td>
<td align="center">6</td>
</tr>
<tr>
<td></td>
<td>01_enum_spec</td>
<td align="center">17</td>
<td align="center">8</td>
<td align="center">09</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>02_slice_spec</td>
<td align="center">144</td>
<td align="center">116</td>
<td align="center">28</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>03_nmatrix_monkeys_spec</td>
<td align="center">12</td>
<td align="center">11</td>
<td align="center">01</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>elementwise_spec</td>
<td align="center">38</td>
<td align="center">21</td>
<td align="center">17</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>homogeneous_spec.rb</td>
<td align="center">07</td>
<td align="center">06</td>
<td align="center">01</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>math_spec</td>
<td align="center">737</td>
<td align="center">541</td>
<td align="center">196</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>shortcuts_spec</td>
<td align="center">81</td>
<td align="center">57</td>
<td align="center">24</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>stat_spec</td>
<td align="center">72</td>
<td align="center">40</td>
<td align="center">32</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>slice_set_spec</td>
<td align="center">6</td>
<td align="center">2</td>
<td align="center">04</td>
<td align="center">0</td>
</tr>
</tbody>
</table>


<br>


<h4>Why do some tests fail?</h4>

<ol>
<li>Complex dtype has not been implemented.</li>
<li>Sparse matrices (list and yale) have not been implemented.</li>
<li>Decomposition methods that are specific to LAPACK and ATLAS have not been implemented.</li>
<li>Integer dtype is not properly assigned to <code>floor</code>, <code>ceil</code>, and <code>round</code> methods.</li>
</ol>


<h3>Mixed_Models</h3>

<table>
<thead>
<tr>
<th></th>
<th>Spec file</th>
<th align="center">Total Test</th>
<th align="center">Success</th>
<th align="center">Failure</th>
<th align="center">Pending</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>Deviance_spec</td>
<td align="center">04</td>
<td align="center">04</td>
<td align="center">0</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>LMM_spec</td>
<td align="center">195</td>
<td align="center">195</td>
<td align="center">0</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>LMM_categorical_data_spec.rb</td>
<td align="center">48</td>
<td align="center">45</td>
<td align="center">3</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>LMMFormula_spec.rb</td>
<td align="center">05</td>
<td align="center">05</td>
<td align="center">0</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>LMM_interaction_effects_spec.rb</td>
<td align="center">82</td>
<td align="center">82</td>
<td align="center">0</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>LMM_nested_effects_spec.rb</td>
<td align="center">40</td>
<td align="center">40</td>
<td align="center">0</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>matrix_methods_spec.rb</td>
<td align="center">52</td>
<td align="center">52</td>
<td align="center">0</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>ModelSpecification_spec.rb</td>
<td align="center">07</td>
<td align="center">07</td>
<td align="center">0</td>
<td align="center">0</td>
</tr>
<tr>
<td></td>
<td>NelderMeadWithConstraints_spec.rb</td>
<td align="center">08</td>
<td align="center">08</td>
<td align="center">0</td>
<td align="center">0</td>
</tr>
</tbody>
</table>


<h2>Future Work</h2>

<p>NMatrix on JRuby offers comparable speeds to MRI. For specific
computations it will be possible to leverage the threading support of
JRuby and speed up things using multiple cores.</p>

<p>Adding new functionality to NMatrix-JRuby will be easy from
here. Personally, I am interested to add OpenCL support to leverage
the GPU computational capacity available on most machines today.</p>

<h2>Conclusion</h2>

<p>The main goal of this project was to to gain from the performance JRuby offers,
and bring a unified interface for linear algebra between MRI and JRuby.</p>

<p>By the end of GSoC, I have been able to successfully create a linear
algebra library, NMatrix for JRuby users, which they can easily run on
their machines &mdash; unless they want to use complex numbers, at
least for now.</p>

<p>I have mixed_models gem simultaneously ported to JRuby. Even here,
NMatrix-JRuby is very close to NMatrix-MRI, considering the performance .</p>

<h2>Acknowledgements</h2>

<p>I would like to express my sincere gratitude to my mentor Pjotr Prins
for the continuous support through the summers, and for his patience,
motivation, enthusiasm, and immense knowledge. I could not have
imagined having a better advisor and mentor, for this project.</p>

<p>I am very grateful to Google and the Ruby Science Foundation for this
golden opportunity.</p>

<p>I am very thankful to Charles Nutter, John Woods, Sameer Deshmukh,
Kenta Murata and Alexej Gossmann, who mentored me through the
project. It has been a great learning experience.</p>

<p>I thank my fellow GSoC participants Rajith, Lokesh and Gaurav who
helped me with certain aspects of my project.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSOC 2016 : Final Report (SpiceRub)]]></title>
    <link href="http://sciruby.com/blog/2016/08/23/spice_rub_report/"/>
    <updated>2016-08-23T00:00:35+05:30</updated>
    <id>http://sciruby.com/blog/2016/08/23/spice_rub_report</id>
    <content type="html"><![CDATA[<p>Finally, GSOC 2016 has come to an end. This last blog post will aim to sum up the work done in these
past few months and how the project can proceed to hit more milestones. Below are some links to my work :-</p>

<p><a href="http://github.com/gau27/spice_rub">Working Repository</a> : GitHub Repo</p>

<p><a href="https://github.com/gau27/spice_rub/commits/master">List of Commits</a> : List of commits to the above repository</p>

<p><a href="https://github.com/gau27/spice_rub/tree/master/examples">Example iRuby Notebooks</a> : A bunch of iRuby Notebook examples of the Ruby API</p>

<p>Firstly, I must admit that I was unable to meet all the goals of my proposal. In retrospect, perhaps it was a bit too ambitious for my skill level at the time, and I undoubtedly spent a lot of time learning, about Ruby-C extensions, the SPICE Toolkit, and good Ruby code and API.</p>

<p>General software requirements such as a shippable gem with an install script that downloads the correct binary dependencies and a dataset fetcher were among the targets in my proposal that I could not meet. If you&#8217;d like to read the full proposal, you can have a look at it <a href="https://summerofcode.withgoogle.com/serve/5210336198131712/">here</a>.</p>

<p>With that said, I am happy with what I did complete, and along with most of the functions in the proposal list being ported successfuly, I have added 3 Ruby classes to provide a better abstracted experience while using the Ephemerides subsystem of SPICE. Given the vastness of SPICE itself, this seems like meagre coverage, but it is a stepping stone that I (and I hope others) would build upon.</p>

<h2><strong>The SpiceRub API</strong></h2>

<p>Please follow the blog links below to read the posts concerning the Ruby classes, the posts basically demonstrate the simple API that can be used for various tasks involving ephemerides. It would help if you followed the order of the links below as they build on top of each other.</p>

<p><a href="http://sciruby.com/blog/2016/11/24/spicerub-kernelpool-and-kernels/">KernelPool</a> :- A Singleton class to handle the loading and unloading of SPICE Data (Kernels)</p>

<p><a href="http://sciruby.com/blog/2016/11/24/gsoc-2016-a-look-at-spicerub-time/">Time</a> :- A class that references ephemeris time and has flexible construction functions</p>

<p><a href="http://sciruby.com/blog/2016/11/24/gsoc-2016-a-look-at-spicerub-body/">Body</a> :- A class that represents a body in space whose motion can be observed with respect to another body.</p>

<p>I spent majority of the post mid-term period on the latter two classes, while most of the time before was spent on writing C extensions to port the SPICE API to Ruby. (and learning good  <code>spec</code> manners, something that was not that quick to grow on me but towards the end got ingrained into me)</p>

<p>I ran into a lot of bugs, learnt more about compiler flags and other building options, and it gave me surprisingly good exposure to low level language trivia for a high level Ruby project. Honestly, I can type <code>SpiceRub</code> faster than most words on my keyboard now =)</p>

<h2><strong>Future Road Map</strong></h2>

<p>Things that I&#8217;ll tackle (after a short break) include :-</p>

<p>1) Installation Integrity so that <code>gem install</code> does everything needed for installation.</p>

<p>2) Complete Documentation</p>

<p>3) The test coverage of SpiceRub::Time is currently lacking because I changed the API at the last minute, but as most of these functions wrap around Native functions that have already been tested, this won&#8217;t be too high a priority, but it will be done.</p>

<p>4) Kernel Fetcher Script : Having to crawl the web for relevant Kernels was a massive headache during this project, and adding something that directly refers to NAIF&#8217;s FTP servers would be a neat addition.</p>

<p>5) Expand the API : There is a lot of SPICE concept I am not well versed with, and there are a bunch of functions ported that would work very well with a better API. (Most immediate task I can see is making a better API for the Geometry Finder subsystem, of which many functions have already been ported in <code>/ext/spice_rub/spice_geometry.c</code>)</p>

<h2><strong>Acknowledgements</strong></h2>

<p>I&#8217;d like to thank my mentors for this project, Dr. John Woods, Shaun Stewart, and Victor Shepelev for their guidance and knowledge. John and Shaun with their expertise in Astro research and Victor&#8217;s vast knowledge about professional Ruby code has helped keep this whole ship together, and I&#8217;m looking forward to sailing it a few more journeys.</p>

<p>Also, John made <a href="https://github.com/sciruby/nmatrix">NMatrix</a> which is sort of the backbone for a lot of SpiceRub&#8217;s functionality.</p>

<p>Finally, I would like to thank Andrew Annex who wrote <a href="https://github.com/AndrewAnnex/SpiceyPy">SpicePy</a>, and Philip Rasch who wrote <a href="https://github.com/darasch/spiceminer">spiceminer</a> , two Python wrappers for the SPICE Toolkit. SpicePy has a high port and test coverage (I lifted a lot of tests from here that weren&#8217;t available in the SPICE documentation and SpiceMiner had an OOP style API which I referred to while designing the <code>Body</code> class.</p>

<p>It&#8217;s been an incredible summer, thank you for reading :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Statistical linear mixed models in Ruby with mixed_models (GSoC2015)]]></title>
    <link href="http://sciruby.com/blog/2015/08/19/gsoc-2015-mixed-models/"/>
    <updated>2015-08-19T12:00:00+05:30</updated>
    <id>http://sciruby.com/blog/2015/08/19/gsoc-2015-mixed-models</id>
    <content type="html"><![CDATA[<p>Google Summer of Code 2015 is coming to an end. During this summer, I have learned too many things to list here about statistical modeling, Ruby and software development in general, and I had a lot of fun in the process!</p>

<h2>Linear mixed models</h2>

<p>My GSoC project is the Ruby gem <a href="https://github.com/agisga/mixed_models">mixed_models</a>. Mixed models are statistical models which predict the value of a response variable as a result of fixed and random effects. The gem in its current version can be used to fit statistical linear mixed models and perform statistical inference on the model parameters as well as to predict future observations. A number of tutorials/examples in IRuby notebook format are accessible from the <code>mixed_models</code> <a href="https://github.com/agisga/mixed_models">github repository</a>.</p>

<p>Linear mixed models are implemented in the class <code>LMM</code>. The constructor method <code>LMM#initialize</code> provides a flexible model specification interface, where an arbitrary covariance structure of the random effects terms can be passed as a <code>Proc</code> or a block.</p>

<p>A convenient user-friendly interface to the basic model fitting algorithm is <code>LMM#from_formula</code>, which uses the formula language of the R mixed models package <code>lme4</code> for model specification. With the <code>#from_formula</code> method, the user can conveniently fit models with categorical predictor variables, interaction fixed or random effects, as well as multiple crossed or nested random effects, all with just one line of code.</p>

<p>Examples are given in the sections below.</p>

<h3>Implementation</h3>

<p>The parameter estimation in <code>LMM#initialize</code> is largely based on the approach developed by the authors of the R mixed models package <code>lme4</code>, which is delineated in the <code>lme4</code> <a href="https://cran.r-project.org/web/packages/lme4/vignettes/lmer.pdf">vignette</a>. I have tried to make the code of the model fitting algorithm in <code>LMM#initialize</code> easy to read, especially compared to the corresponding implementation in <code>lme4</code>.</p>

<p>The <code>lme4</code> code is largely written in C++, which is integrated in R via the packages <code>Rcpp</code> and <code>RcppEigen</code>. It uses <a href="https://developer.nvidia.com/cholmod">CHOLMOD</a> code for various sparse matrix tricks, and it involves passing pointers to C++ object to R (and vice versa) many times, and passing different R environments from function to function. All this makes the <code>lme4</code> code rather hard to read. Even Douglas Bates, the main developer of <code>lme4</code>, admits that <a href="https://stat.ethz.ch/pipermail/r-sig-mixed-models/2014q4/022791.html">&#8220;The end result is confusing (my fault entirely) and fragile&#8221;</a>, because of all the utilized performance improvements. I have analyzed the <code>lme4</code> code in three blog posts (<a href="http://agisga.github.io/Dissect_lmer_part1/">part 1</a>, <a href="http://agisga.github.io/Dissect_lmer_part2/">part 2</a> and <a href="http://agisga.github.io/Dissect_lmer_part3/">part 3</a>) before starting to work on my gem <code>mixed_models</code>.</p>

<p>The method <code>LMM#initialize</code> is written in a more functional style, which makes the code shorter and (I find) easier to follow.  All matrix calculations are performed using the gem <a href="https://github.com/SciRuby/nmatrix"><code>nmatrix</code></a>, which has a quite intuitive syntax and contributes to the overall code readability as well.
The Ruby gem loses with respect to memory consumption and speed in comparison to <code>lme4</code>, because it is written in pure Ruby and does not utilize any sparse matrix tricks. However, for the same reasons the <code>mixed_models</code> code is much shorter and easier to read than <code>lme4</code>. Moreover, the linear mixed model formulation in <code>mixed_models</code> is a little bit more general, because it does not assume that the random effects covariance matrix is sparse. More about the implementation of <code>LMM#initialize</code> can be found in <a href="http://agisga.github.io/First-linear-mixed-model-fit/">this blog post</a>.</p>

<h3>Other existing tools</h3>

<p>Popular existing software packages for mixed models include the R package <a href="https://cran.r-project.org/web/packages/lme4/index.html"><code>lme4</code></a> (which is arguably the standard software for linear mixed models), the R package <a href="https://cran.r-project.org/web/packages/nlme/index.html"><code>nlme</code></a> (an older package developed by the same author as <code>lme4</code>, still widely used), Python&#8217;s <a href="https://github.com/statsmodels/statsmodels/blob/master/statsmodels/regression/mixed_linear_model.py"><code>statmodels</code></a>, and the Julia package <a href="https://github.com/dmbates/MixedModels.jl"><code>MixedModels.jl</code></a>.</p>

<p>Below, I give a couple of examples illustrating some of the capabilities of <code>mixed_models</code> and explore how it compares to the alternatives.</p>

<h3>A usage example and discussion</h3>

<p>As an example, we use <a href="http://archive.ics.uci.edu/ml/datasets/BlogFeedback">data</a> from the UCI machine learning repository, which originate from blog posts from various sources in 2010-2012, in order to model (the logarithm of) the number of comments that a blog post receives. The linear predictors are the text length, the log-transform of the average number of comments at the hosting website, the average number of trackbacks at the hosting website, and the parent blog posts. We assume a random effect on the number of comments due to the day of the week on which the blog post was published. In <code>mixed_models</code> this model can be fit with</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">model_fit</span> <span class="o">=</span> <span class="no">LMM</span><span class="o">.</span><span class="n">from_formula</span><span class="p">(</span><span class="ss">formula</span><span class="p">:</span> <span class="s2">&quot;log_comments ~ log_host_comments_avg + host_trackbacks_avg + length + has_parent_with_comments + (1 | day)&quot;</span><span class="p">,</span>
</span><span class='line'>                              <span class="ss">data</span><span class="p">:</span> <span class="n">blog_data</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>and we can display some information about the estimated fixed effects with</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">puts</span> <span class="n">model_fit</span><span class="o">.</span><span class="n">fix_ef_summary</span><span class="o">.</span><span class="n">inspect</span><span class="p">(</span><span class="mi">24</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>which produces the following output:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>                                         <span class="n">coef</span>                       <span class="n">sd</span>                  <span class="n">z_score</span>            <span class="no">WaldZ_p_value</span>
</span><span class='line'>           <span class="n">intercept</span>       <span class="mi">1</span><span class="o">.</span><span class="mi">2847896684307731</span>     <span class="mi">0</span><span class="o">.</span><span class="mo">0303</span><span class="mi">80582281933178</span>        <span class="mi">42</span><span class="o">.</span><span class="mi">28983027737477</span>                      <span class="mi">0</span><span class="o">.</span><span class="mi">0</span>
</span><span class='line'>   <span class="n">log_host_comments_avg</span>        <span class="mi">0</span><span class="o">.</span><span class="mi">415586319225577</span>     <span class="mi">0</span><span class="o">.</span><span class="mo">007</span><span class="mi">848368759350875</span>        <span class="mi">52</span><span class="o">.</span><span class="mi">95193586953086</span>                      <span class="mi">0</span><span class="o">.</span><span class="mi">0</span>
</span><span class='line'> <span class="n">host_trackbacks_avg</span>     <span class="o">-</span><span class="mi">0</span><span class="o">.</span><span class="mo">075515</span><span class="mi">88997745964</span>     <span class="mi">0</span><span class="o">.</span><span class="mo">010</span><span class="mi">915623834434068</span>       <span class="o">-</span><span class="mi">6</span><span class="o">.</span><span class="mi">918146971979714</span>    <span class="mi">4</span><span class="o">.</span><span class="mi">575895218295045</span><span class="n">e</span><span class="o">-</span><span class="mi">12</span>
</span><span class='line'>              <span class="n">length</span>   <span class="mi">1</span><span class="o">.</span><span class="mi">8245853808280765</span><span class="n">e</span><span class="o">-</span><span class="mo">05</span>    <span class="mi">2</span><span class="o">.</span><span class="mi">981631039432429</span><span class="n">e</span><span class="o">-</span><span class="mo">06</span>        <span class="mi">6</span><span class="o">.</span><span class="mi">119420400102211</span>    <span class="mi">9</span><span class="o">.</span><span class="mi">391631916599863</span><span class="n">e</span><span class="o">-</span><span class="mi">10</span>
</span><span class='line'><span class="n">has_parent_with_comments</span>      <span class="o">-</span><span class="mi">0</span><span class="o">.</span><span class="mi">4616662830553772</span>      <span class="mi">0</span><span class="o">.</span><span class="mi">13936886611993773</span>      <span class="o">-</span><span class="mi">3</span><span class="o">.</span><span class="mi">3125496095955715</span>    <span class="mi">0</span><span class="o">.</span><span class="mo">000</span><span class="mi">9244972814528296</span>
</span></code></pre></td></tr></table></div></figure>


<p>We can also display the estimated random effects coefficients and the random effects standard deviation,</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">puts</span> <span class="s2">&quot;Random effects coefficients:&quot;</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">model_fit</span><span class="o">.</span><span class="n">ran_ef</span>
</span><span class='line'><span class="nb">puts</span> <span class="s2">&quot;Random effects correlation structure:&quot;</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">model_fit</span><span class="o">.</span><span class="n">ran_ef_summary</span><span class="o">.</span><span class="n">inspect</span>
</span></code></pre></td></tr></table></div></figure>


<p>which produces</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Random</span> <span class="n">effects</span> <span class="ss">coefficients</span><span class="p">:</span>
</span><span class='line'><span class="p">{</span><span class="ss">:intercept_fr</span><span class="o">=&gt;</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">:intercept_mo</span><span class="o">=&gt;</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">:intercept_sa</span><span class="o">=&gt;</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">:intercept_su</span><span class="o">=&gt;</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">:intercept_th</span><span class="o">=&gt;</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">:intercept_tu</span><span class="o">=&gt;</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="p">,</span> <span class="ss">:intercept_we</span><span class="o">=&gt;</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="p">}</span>
</span><span class='line'><span class="no">Random</span> <span class="n">effects</span> <span class="n">standard</span> <span class="ss">deviation</span><span class="p">:</span>
</span><span class='line'>
</span><span class='line'><span class="c1">#&lt;Daru::DataFrame:70278348234580 @name = 8e11a27f-81b0-48a0-9771-085a8f30693d @size = 1&gt;</span>
</span><span class='line'>                  <span class="n">day</span>
</span><span class='line'>       <span class="n">day</span>        <span class="mi">0</span><span class="o">.</span><span class="mi">0</span>
</span></code></pre></td></tr></table></div></figure>


<p>Interestingly, the estimates of the random effects coefficients and standard deviation are all zero!
That is, we have a singular fit. Thus, our results imply that the day of the week on which a blog post is published has no effect on the number of comments that the blog post will receive.</p>

<p>It is worth pointing out that such a model fit with a singular covariance matrix is problematic with the current version of Python&#8217;s <code>statmodels</code> (described as &#8220;numerically challenging&#8221; in the <a href="http://statsmodels.sourceforge.net/devel/mixed_linear.html">documentation</a>) and the R package <code>nlme</code> (&#8220;Singular covariance matrices correspond to infinite parameter values&#8221;, a <a href="https://stat.ethz.ch/pipermail/r-sig-mixed-models/2014q4/022791.html">mailing list reply</a> by Douglas Bates, the author of <code>nlme</code>). However, <code>mixed_models</code>, <code>lme4</code> and <code>MixedModels.jl</code> can handle singular fits without problems.
In fact, like <code>mixed_models</code> above, <code>lme4</code> estimates the random effects coefficients and standard deviation to be zero, as we can see from the following R output:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='rconsole'><span class='line'><span class="gp">&gt; </span>mod <span class="o">&lt;-</span> lmer<span class="p">(</span>log_comments <span class="o">~</span> log_host_comments_avg <span class="o">+</span> host_trackbacks_avg <span class="o">+</span> length <span class="o">+</span> has_parent_with_comments <span class="o">+</span> <span class="p">(</span><span class="m">1</span><span class="o">|</span>day<span class="p">),</span> data <span class="o">=</span> df<span class="p">)</span>
</span><span class='line'><span class="go">Warning message:</span>
</span><span class='line'><span class="go">Some predictor variables are on very different scales: consider rescaling </span>
</span><span class='line'><span class="gp">&gt; </span>ranef<span class="p">(</span>mod<span class="p">)</span>
</span><span class='line'><span class="go">$day</span>
</span><span class='line'><span class="go">   (Intercept)</span>
</span><span class='line'><span class="go">fr           0</span>
</span><span class='line'><span class="go">mo           0</span>
</span><span class='line'><span class="go">sa           0</span>
</span><span class='line'><span class="go">su           0</span>
</span><span class='line'><span class="go">th           0</span>
</span><span class='line'><span class="go">tu           0</span>
</span><span class='line'><span class="go">we           0</span>
</span><span class='line'>
</span><span class='line'><span class="gp">&gt; </span>VarCorr<span class="p">(</span>mod<span class="p">)</span>
</span><span class='line'><span class="go"> Groups   Name        Std.Dev.</span>
</span><span class='line'><span class="go"> day      (Intercept) 0.0000  </span>
</span><span class='line'><span class="go"> Residual             1.2614</span>
</span></code></pre></td></tr></table></div></figure>


<p>Unfortunately, <code>mixed_models</code> is rather slow when applied to such a large data set (<code>blog_data</code> is a data frame of size 22435&times;8), especially when compared to <code>lme4</code> which uses many sparse matrix tricks and is mostly written in C++ (integrated in R via <code>Rcpp</code>) to speed up computation. The difference in performance between <code>mixed_models</code> and <code>lme4</code> is on the order of hours for large data, and Julia&#8217;s <code>MixedModels.jl</code> promises to be even faster than <code>lme4</code>. However, there is no noticeable difference in performance speed for smaller data sets.</p>

<p><a href="http://nbviewer.ipython.org/github/agisga/mixed_models/blob/master/notebooks/blog_data.ipynb">The full data analysis of the blog post data can be found in this IRuby notebook</a>.</p>

<h3>A second example and statistical inference on the parameter estimates</h3>

<p>Often, the experimental design or the data suggests a linear mixed model whose random effects are associated with multiple grouping factors. A specification of multiple random effects terms which correspond to multiple grouping factors is often referred to as <em>crossed random effect</em>, or <em>nested random effects</em> if the corresponding grouping factors are nested in each other.
A good reference on such models is <a href="http://lme4.r-forge.r-project.org/book/Ch2.pdf">Chapter 2</a> of Douglas Bates&#8217; <code>lme4</code> book.</p>

<p>Like <code>lme4</code>, <code>mixed_models</code> is particularly well suited for models with crossed or nested random effects. The current release of <code>statmodels</code>, however, does not support crossed or nested random effects (according to the <a href="http://statsmodels.sourceforge.net/devel/mixed_linear.html">documentation</a>).</p>

<p>As an example we fit a linear mixed model with nested random effects to a data frame with 100 rows, of the form:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1">#&lt;Daru::DataFrame:69912847885160 @name = 2b161c5d-00de-4240-be50-8fa84f3aed24 @size = 5&gt;</span>
</span><span class='line'>                    <span class="n">a</span>          <span class="n">b</span>          <span class="n">x</span>          <span class="n">y</span>
</span><span class='line'>         <span class="mi">0</span>         <span class="n">a3</span>         <span class="n">b1</span> <span class="mi">0</span><span class="o">.</span><span class="mi">38842531</span> <span class="mi">5</span><span class="o">.</span><span class="mi">10364866</span>
</span><span class='line'>         <span class="mi">1</span>         <span class="n">a3</span>         <span class="n">b2</span> <span class="mi">0</span><span class="o">.</span><span class="mi">44622300</span> <span class="mi">6</span><span class="o">.</span><span class="mi">23307061</span>
</span><span class='line'>         <span class="mi">2</span>         <span class="n">a3</span>         <span class="n">b1</span> <span class="mi">1</span><span class="o">.</span><span class="mi">54993657</span> <span class="mi">12</span><span class="o">.</span><span class="mi">2050404</span>
</span><span class='line'>         <span class="mi">3</span>         <span class="n">a3</span>         <span class="n">b1</span> <span class="mi">1</span><span class="o">.</span><span class="mi">52786614</span> <span class="mi">12</span><span class="o">.</span><span class="mo">00675</span><span class="mi">95</span>
</span><span class='line'>         <span class="mi">4</span>         <span class="n">a3</span>         <span class="n">b2</span> <span class="mi">0</span><span class="o">.</span><span class="mi">76011212</span> <span class="mi">8</span><span class="o">.</span><span class="mi">20054527</span>
</span></code></pre></td></tr></table></div></figure>


<p>We consider the following model:</p>

<ul>
<li>We take <code>y</code> to be the response and <code>x</code> its predictor.</li>
<li>We consider the factor <code>b</code> to be nested within the factor <code>a</code>.</li>
<li>We assume that the intercept varies due to variable <code>a</code>; that is, a different (random) intercept term for each level of <code>a</code>.</li>
<li>Moreover, we assume that the intercept varies due to the factor <code>b</code> which is nested in <code>a</code>; that is, different (random) intercept for each combination of levels of <code>a</code> and <code>b</code>.</li>
</ul>


<p>That is, mathematically the model can be expressed as</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">y</span> <span class="o">=</span> <span class="n">beta_0</span> <span class="o">+</span> <span class="n">beta_1</span> <span class="o">*</span> <span class="n">x</span> <span class="o">+</span> <span class="n">gamma</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">+</span> <span class="n">delta</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span> <span class="o">+</span> <span class="n">epsilon</span>
</span></code></pre></td></tr></table></div></figure>


<p>where <code>gamma(a) ~ N(0, phi**2)</code> and <code>delta(a,b) ~ N(0, psi**2)</code> are normally distributed random variables which assume different realizations for different values of <code>a</code> and <code>b</code>, and where <code>epsilon</code> is a random Gaussian noise term with variance <code>sigma**2</code>. The goal is to estimate the parameters <code>beta_0</code>, <code>beta_1</code>, <code>phi</code>, <code>psi</code> and <code>sigma</code>.</p>

<p>We fit this model in <code>mixed_models</code>, and display the estimated random effects correlation structure with</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">mod</span> <span class="o">=</span> <span class="no">LMM</span><span class="o">.</span><span class="n">from_formula</span><span class="p">(</span><span class="ss">formula</span><span class="p">:</span> <span class="s2">&quot;y ~ x + (1|a) + (1|a:b)&quot;</span><span class="p">,</span>
</span><span class='line'>                       <span class="ss">data</span><span class="p">:</span> <span class="n">df</span><span class="p">,</span> <span class="ss">reml</span><span class="p">:</span> <span class="kp">false</span><span class="p">)</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">mod</span><span class="o">.</span><span class="n">ran_ef_summary</span><span class="o">.</span><span class="n">inspect</span>
</span></code></pre></td></tr></table></div></figure>


<p>which produces the output</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>                <span class="n">a</span>    <span class="n">a_and_b</span>
</span><span class='line'>     <span class="n">a</span> <span class="mi">1</span><span class="o">.</span><span class="mi">34108300</span>        <span class="kp">nil</span>
</span><span class='line'>   <span class="n">a_and_b</span>        <span class="kp">nil</span> <span class="mi">0</span><span class="o">.</span><span class="mi">97697500</span>
</span></code></pre></td></tr></table></div></figure>


<p>The correlation between the factor <code>a</code> and the nested random effect <code>a_and_b</code> is denoted as <code>nil</code>, because the random effects in the model at hand are assumed to be independent.</p>

<p>An advantage of <code>mixed_models</code> over some other tools is the simplicity with which p-values and confidence intervals for the parameter estimates can be calculated using a multitude of available methods. Such methods include a likelihood ratio test implementation, multiple bootstrap based methods (which run in parallel by default), and methods based on the Wald Z statistic.</p>

<p>We can compute five types of 95% confidence intervals for the fixed effects coefficients with the following line of code:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">mod</span><span class="o">.</span><span class="n">fix_ef_conf_int</span><span class="p">(</span><span class="nb">method</span><span class="p">:</span> <span class="ss">:all</span><span class="p">,</span> <span class="ss">nsim</span><span class="p">:</span> <span class="mi">1000</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>which yields the result</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>                                      <span class="n">intercept</span>                                        <span class="n">x</span>
</span><span class='line'><span class="n">wald_z</span> <span class="o">[-</span><span class="mi">1</span><span class="o">.</span><span class="mo">0442515623151203</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">433416817887737</span><span class="o">]</span>   <span class="o">[</span><span class="mi">4</span><span class="o">.</span><span class="mi">302419420148841</span><span class="p">,</span> <span class="mi">5</span><span class="o">.</span><span class="mo">03</span><span class="mi">8899876985704</span><span class="o">]</span>
</span><span class='line'><span class="n">boot_basic</span> <span class="o">[-</span><span class="mi">0</span><span class="o">.</span><span class="mi">9676586601496888</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">486799230544233</span><span class="o">]</span>    <span class="o">[</span><span class="mi">4</span><span class="o">.</span><span class="mi">30540212917657</span><span class="p">,</span> <span class="mi">5</span><span class="o">.</span><span class="mo">02</span><span class="mi">8701160534481</span><span class="o">]</span>
</span><span class='line'> <span class="n">boot_norm</span> <span class="o">[-</span><span class="mi">1</span><span class="o">.</span><span class="mo">05755200</span><span class="mi">80398213</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">4667867000424115</span>   <span class="o">[</span><span class="mi">4</span><span class="o">.</span><span class="mi">295959190826356</span><span class="p">,</span> <span class="mi">5</span><span class="o">.</span><span class="mo">0433</span><span class="mi">82379744274</span><span class="o">]</span>
</span><span class='line'><span class="n">boot_t</span> <span class="o">[-</span><span class="mi">0</span><span class="o">.</span><span class="mi">9676586601496886</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">486799230544233</span><span class="o">]</span>    <span class="o">[</span><span class="mi">4</span><span class="o">.</span><span class="mi">30540212917657</span><span class="p">,</span> <span class="mi">5</span><span class="o">.</span><span class="mo">02</span><span class="mi">8701160534481</span><span class="o">]</span>
</span><span class='line'> <span class="n">boot_perc</span> <span class="o">[-</span><span class="mi">1</span><span class="o">.</span><span class="mi">0976339749716164</span><span class="p">,</span> <span class="mi">2</span><span class="o">.</span><span class="mi">3568239157223054</span>   <span class="o">[</span><span class="mi">4</span><span class="o">.</span><span class="mi">312618136600064</span><span class="p">,</span> <span class="mi">5</span><span class="o">.</span><span class="mo">035</span><span class="mi">917167957975</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>For example, we see here that the intercept term is likely not significantly different from zero. We could proceed now by performing hypotheses tests using <code>#fix_ef_p</code> or <code>#likelihood_ratio_test</code>, or by refitting a model without an intercept using <code>#drop_fix_ef</code>.</p>

<p>We can also test the nested random effect for significance, in order to decide whether we should drop that term from the model to reduce model complexity. We can use a bootstrap based version of likelihood ratio test as follows.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">mod</span><span class="o">.</span><span class="n">ran_ef_p</span><span class="p">(</span><span class="ss">variable</span><span class="p">:</span> <span class="ss">:intercept</span><span class="p">,</span> <span class="ss">grouping</span><span class="p">:</span> <span class="o">[</span><span class="ss">:a</span><span class="p">,</span> <span class="ss">:b</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>             <span class="nb">method</span><span class="p">:</span> <span class="ss">:bootstrap</span><span class="p">,</span> <span class="ss">nsim</span><span class="p">:</span> <span class="mi">1000</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>We get a p-value of 9.99e-4, suggesting that we probably should keep the term <code>(1|a:b)</code> in the model formula.</p>

<h3>A third example &mdash; a less conventional model fit</h3>

<p>Another advantage of <code>mixed_models</code> against comparable tools is the ease of fitting models with arbitrary covariance structures of the random effects, which are not covered by the formula interface of <code>lme4</code>. This can be done in a user-friendly manner by providing a block or a <code>Proc</code> to the <code>LMM</code> constructor. This unique feature of the Ruby language makes the implementation and usage of the method incredibly convenient. A danger of allowing for arbitrary covariance structures is, of course, that such a flexibility gives the user the freedom to specify degenerate and computationally unstable  models.</p>

<p>As an example we look at an application to genetics, namely to SNP data (<a href="https://en.wikipedia.org/wiki/Single-nucleotide_polymorphism">single-nucleotide polymorphism</a>) with known pedigree structures (family relationships of the subjects). The family information is prior knowledge that we can model in the random effects of a linear mixed effects model.</p>

<p>We model the quantitative trait <code>y</code> (a vector of length 1200) as</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">y</span> <span class="o">=</span> <span class="n">X</span> <span class="o">*</span> <span class="n">beta</span> <span class="o">+</span> <span class="n">b</span> <span class="o">+</span> <span class="n">epsilon</span><span class="p">,</span>
</span></code></pre></td></tr></table></div></figure>


<p>where <code>X</code> is a <code>1200 x 130</code> matrix containing the genotypes (i.e. 130 SNPs for each of the 1200 subjects); <code>epsilon</code> is a vector of independent random noise terms with variances equal to <code>sigma**2</code>; <code>beta</code> is a vector of unknown fixed effects coefficients measuring the contribution of each SNP to the quantitative trait <code>y</code>; and <code>b</code> is a vector of random effects.</p>

<p>If we denote the kinship matrix by <code>K</code>, then we can express the probability distribution of <code>b</code> as <code>b ~ N(0, delta**2 * 2 * K)</code>, where we multiply <code>K</code> by <code>2</code> because the diagonal of <code>K</code> is constant <code>0.5</code>, and where <code>delta**2</code> is a unknown scaling factor.</p>

<p>The goal is to estimate the unknown parameters <code>beta</code>, <code>sigma</code>, and <code>delta</code>, and to determine which of the fixed effects coefficients are significantly different from 0 (i.e. which SNPs are possibly causing the variability in the trait <code>y</code>).</p>

<p>In order to specify the covariance structure of the random effects, we need to pass a block or <code>Proc</code> that produces the upper triangular Cholesky factor of the covariance matrix of the random effects from an input Array. In this example, that would be the multiplication of the prior known Cholesky factor of the kinship matrix with a scaling factor.</p>

<p>Having all the model matrices and vectors, we compute the Cholesky factor of the kinship matrix and fit the model with</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># upper triangulat Cholesky factor</span>
</span><span class='line'><span class="n">kinship_mat_cholesky_factor</span> <span class="o">=</span> <span class="n">kinship_mat</span><span class="o">.</span><span class="n">factorize_cholesky</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Fit the model</span>
</span><span class='line'><span class="n">model_fit</span> <span class="o">=</span> <span class="no">LMM</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">x</span><span class="p">:</span> <span class="n">x</span><span class="p">,</span> <span class="ss">y</span><span class="p">:</span> <span class="n">y</span><span class="p">,</span> <span class="ss">zt</span><span class="p">:</span> <span class="n">z</span><span class="p">,</span>
</span><span class='line'>                    <span class="ss">x_col_names</span><span class="p">:</span> <span class="n">x_names</span><span class="p">,</span>
</span><span class='line'>                    <span class="ss">start_point</span><span class="p">:</span> <span class="o">[</span><span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'>                    <span class="ss">lower_bound</span><span class="p">:</span> <span class="o">[</span><span class="mi">0</span><span class="o">.</span><span class="mi">0</span><span class="o">]</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">th</span><span class="o">|</span> <span class="n">kinship_mat_cholesky_factor</span> <span class="o">*</span> <span class="n">th</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then we can use the available hypotheses test and confidence interval methods to determine which SNPs are significant predictors of the quantitative trait. Out of the 130 SNPs in the model, we find 24 to be significant as linear predictors.</p>

<p>See <a href="http://agisga.github.io/mixed_models_applied_to_family_SNP_data/">this blog post</a> for a full analysis of this data with <code>mixed_models</code>.</p>

<h2>Room for improvement and future work</h2>

<ul>
<li><p>Writing the formula language interpretation code used by <code>LMM#from_formula</code> from scratch was not easy. Much of the code can be reorganized to be easier to read and to use in other projects. Possibly, the formula interface should be separated out, similar to how it is done with the Python package <a href="https://github.com/pydata/patsy">patsy</a>. Also, some shortcut symbols (namely <code>*</code>, <code>/</code>, and <code>||</code>) in the model specification formula language are currently not implemented.</p></li>
<li><p>I plan to add linear mixed models for high-dimensional data (i.e. more predictors than observations) to <code>mixed_models</code>, because that work would be in line with my current PhD research.</p></li>
<li><p>I plan to add generalized linear mixed models capabilities to <code>mixed_models</code>, which can be used to fit mixed models to discrete data (such as binary or count data).</p></li>
</ul>


<h2>Acknowledgement</h2>

<p>I want to thank Google and the <a href="sciruby.com">Ruby Science Foundation</a> for giving me this excellent opportunity! I especially want to thank <a href="http://thebird.nl/">Pjotr Prins</a> who was my mentor for the project for much helpful advice and suggestions as well as his prompt responses to any of my concerns. I also want to thank my fellow GSoC participants <a href="https://github.com/wlevine">Will</a>, <a href="https://github.com/dilcom">Ivan</a>, and <a href="https://github.com/v0dro">Sameer</a> for their help with certain aspects of my project.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GSoC 2015: New NMatrix gems for advanced linear algebra features]]></title>
    <link href="http://sciruby.com/blog/2015/08/19/gsoc-2015-nmatrix/"/>
    <updated>2015-08-19T09:57:00+05:30</updated>
    <id>http://sciruby.com/blog/2015/08/19/gsoc-2015-nmatrix</id>
    <content type="html"><![CDATA[<p>My Google Summer of Code project was working on the <a href="https://github.com/SciRuby/nmatrix">NMatrix project</a>, moving
functionality that depends on external libraries from the core <code>nmatrix</code>
gem to optional plugin gems. NMatrix is a Ruby library for linear algebra,
used by many other projects.
In addition to the code that was part of
NMatrix proper, NMatrix previously required the <a href="http://math-atlas.sourceforge.net/">ATLAS library</a>, which
implemented fast versions of common matrix operations like multiplication
and inversion, as well as more advanced operations like eigenvalue
decomposition and Cholesky decomposition.</p>

<p>There were two separate but related motivations for my project. The
first was to simplify the NMatrix installation
process. ATLAS can be difficult to install, so the installation
process for NMatrix was complicated, especially on
OS X, and may have discouraged people from using NMatrix.
The second motivation was that by separating out the ATLAS code from the
main NMatrix code, it would be easier to add new linear algebra backends
which provide similar features. Indeed, I implemented a second backend this
summer.</p>

<p>The end result of my summer&#8217;s work:</p>

<ul>
<li>The core <code>nmatrix</code> gem does not depend on any external linear matrix
libraries. It provides non-optimized implementations of common matrix
operations.</li>
<li>All code that requires ATLAS has been moved into the new <code>nmatrix-atlas</code>
gem, so that
those who are only interested in the core functionality are not required to
install ATLAS. <code>nmatrix-atlas</code> provides optimized implementations of common matrix
operations, as well as advanced functions not available in <code>nmatrix</code>.
I wrote a blog post describing the setup for <a href="http://wlevine.github.io/2015/06/15/releasing-multiple-gems-with-c-extensions-from-the-same-repository.html">releasing multiple gems from the same repository</a>, which this required.</li>
<li>A new gem <code>nmatrix-lapacke</code>, which provides the same features as
<code>nmatrix-atlas</code>, but instead of depending specifically on the ATLAS
library, requires any generic <a href="https://en.wikipedia.org/wiki/LAPACK">LAPACK</a> and
<a href="https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms">BLAS</a>
implementation. This should be easier to use for many users as they may
already have LAPACK installed (it comes pre-installed with OS X and is
commonly used in Linux systems), but not ATLAS.</li>
<li>The installation procedure is simplified, especially for those installing
just the <code>nmatrix</code> gem. Compare the <a href="https://github.com/SciRuby/nmatrix/wiki/Installation">new installation instructions</a>
to the <a href="https://github.com/SciRuby/nmatrix/wiki/Installation/2ac41c62d35c79468d3d8169be0ccba238c3c921">old ones</a>.</li>
</ul>


<p>The one deviation from my original proposal was that I originally intended to remove
all the ATLAS code and release only the <code>nmatrix-lapacke</code> plugin, so that we
would only have one interface to the advanced linear algebra functions, but I
decided to keep the ATLAS code, since the <code>nmatrix-lapacke</code> code is new and
has not had a chance to be thoroughly tested.</p>

<h3>Usage</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;nmatrix&#39;</span>
</span><span class='line'><span class="c1"># create a 3-by-3 matrix</span>
</span><span class='line'><span class="n">a</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="o">]</span><span class="p">,</span> <span class="ss">dtype</span><span class="p">:</span> <span class="ss">:float64</span><span class="p">)</span>
</span><span class='line'><span class="c1">#invert it using non-optimized NMatrix-internal implementation</span>
</span><span class='line'><span class="n">a</span><span class="o">.</span><span class="n">invert!</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;nmatrix&#39;</span>
</span><span class='line'><span class="nb">require</span> <span class="s1">&#39;nmatrix/atlas&#39;</span> <span class="c1">#or require &#39;nmatrix/lapacke&#39;</span>
</span><span class='line'><span class="c1"># create a 3-by-3 matrix</span>
</span><span class='line'><span class="n">a</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">3</span><span class="p">,</span><span class="mi">3</span><span class="o">]</span><span class="p">,</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="o">]</span><span class="p">,</span> <span class="ss">dtype</span><span class="p">:</span> <span class="ss">:float64</span><span class="p">)</span>
</span><span class='line'><span class="c1">#invert it using optimized implementation provided by ATLAS</span>
</span><span class='line'><span class="n">a</span><span class="o">.</span><span class="n">invert!</span>
</span></code></pre></td></tr></table></div></figure>


<p>For advanced functions not provided by the core <code>nmatrix</code> gem, for example
<a href="http://sciruby.com/nmatrix/docs/NMatrix.html#method-i-gesvd"><code>gesvd</code></a>, <code>nmatrix-atlas</code> and <code>nmatrix-lapacke</code>
provide a common interface:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;nmatrix&#39;</span>
</span><span class='line'><span class="nb">require</span> <span class="s1">&#39;nmatrix/atlas&#39;</span>
</span><span class='line'><span class="n">a</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="o">]</span><span class="p">,</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'><span class="ss">dtype</span><span class="p">:</span> <span class="n">dtype</span><span class="p">)</span>
</span><span class='line'><span class="n">u</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">vt</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="n">gesvd</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1">#Identical to the above, except for the require</span>
</span><span class='line'><span class="nb">require</span> <span class="s1">&#39;nmatrix&#39;</span>
</span><span class='line'><span class="nb">require</span> <span class="s1">&#39;nmatrix/lapacke&#39;</span>
</span><span class='line'><span class="n">a</span> <span class="o">=</span> <span class="no">NMatrix</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="o">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="o">]</span><span class="p">,</span><span class="o">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'><span class="ss">dtype</span><span class="p">:</span> <span class="n">dtype</span><span class="p">)</span>
</span><span class='line'><span class="n">u</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">vt</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="n">gesvd</span>
</span></code></pre></td></tr></table></div></figure>


<p>If the developer wants to use an advanced feature, but does not care
whether the user is using <code>nmatrix-atlas</code>
or <code>nmatrix-lapacke</code>, they can <code>require nmatrix/lapack_plugin</code>, which will
require whichever of the two is available, instead of being forced to
choose between the two.</p>

<p>As a fun test of the new gems, I did a very simple benchmark, just
testing how long it took to invert a
1500-by-1500 matrix in place using <code>NMatix#invert!</code>:</p>

<ul>
<li><code>nmatrix</code> (no external libraries): 3.67s</li>
<li><code>nmatrix-atlas</code>: 0.96s</li>
<li><code>nmatrix-lapacke</code> with ATLAS: 0.99s</li>
<li><code>nmatrix-lapacke</code> with OpenBLAS (multithreading enabled): 0.39s</li>
<li><code>nmatrix-lapacke</code> with reference implementations of LAPACK and BLAS: 3.72s</li>
</ul>


<p>This is not supposed to be a thorough or realistic benchmark (performance will
depend on your system, on how you built the libraries, and on the exact
functions that you use), but there
are still a few interesting conclusions we can draw from it:</p>

<ul>
<li>Performance is much better using the two highly optimized libraries
(ATLAS and OpenBLAS) than using either the NMatrix
internal implementation or the reference implementation.</li>
<li>When using ATLAS, performance is similar whether using <code>nmatrix-atlas</code>
and <code>nmatrix-lapacke</code> (this means we could consider deprecating
the <code>nmatix-atlas</code> gem).</li>
</ul>


<p>Overall, my summer has been productive. I implemented everything that I
proposed and feedback from testers so far has been positive.
I plan to stay involved with NMatrix, especially to follow up on any issues
related to my changes.
Although I won&#8217;t be a student next summer, I would certainly consider
participating in Google Summer of Code in the future as a mentor.
I&#8217;d like to
thank my mentor John Woods and the rest of the SciRuby community for support
and feedback throughout the summer.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GnuplotRB and GSoC 2015]]></title>
    <link href="http://sciruby.com/blog/2015/08/18/gnuplotrb-project/"/>
    <updated>2015-08-18T23:26:00+05:30</updated>
    <id>http://sciruby.com/blog/2015/08/18/gnuplotrb-project</id>
    <content type="html"><![CDATA[<h2>Introduction</h2>

<p>This summer I&#8217;ve been participating in Google Summer of Code
 with <a href="https://github.com/dilcom/gnuplotrb">GnuplotRB project</a> (plotting tool for Ruby users based on <a href="http://www.gnuplot.info/">Gnuplot</a>)
 for <a href="http://sciruby.com/">SciRuby</a>. GSoC is almost over and I&#8217;m releasing v0.3.1 of GnuplotRB as a <a href="https://rubygems.org/gems/gnuplotrb/">gem</a>.
 In this blog post I want to introduce the gem and highlight some of its capabilities.</p>

<h2>Features</h2>

<p>There are several existing plotting tools for Ruby such as Nyaplot, Plotrb, Rubyvis
 and Gnuplot gem. However they are not designed for large datasets and have fewer
 plotting styles and options than Gnuplot. Gnuplot gem was developed long ago and nowadays consists
 mostly of hacks and does not support modern Gnuplot features such as multiplot.</p>

<p>Therefore my goal was to develop new gem for Gnuplot which would allow full use of its
 features in Ruby. I was inspired to build an easy-to-use interface for the most commonly
 used features of Gnuplot and allow users to customize their plots with
 Gnuplot options as easily as possible in Rubyesque way.</p>

<!--more-->


<h3>2D and 3D plots</h3>

<p>The main feature of every plotting tool is its ability to plot graphs. GnuplotRB allows you
 to plot both mathematical formula  and (huge) sets of data. GnuplotRB supports plotting
 2D graphs (<code>GnuplotRB::Plot</code> class)  in Cartesian/parametric/polar coordinates and 3D
 graphs (<code>GnuplotRB::Splot</code> class) &mdash; in Cartesian/cylindrical/spherical coordinates.</p>

<p>There are vast of plotting styles supported by GnuplotRB:</p>

<ul>
<li><code>points</code></li>
<li><code>lines</code></li>
<li><code>histograms</code></li>
<li><code>boxerrorbars</code></li>
<li><code>circles</code></li>
<li><code>boxes</code></li>
<li><code>filledcurves</code></li>
<li><code>vectors</code></li>
<li><code>heatmap</code></li>
<li>etc (full list in <a href="http://www.gnuplot.info/docs_5.0/gnuplot.pdf">gnuplot doc</a> p. 47)</li>
</ul>


<p>Plot examples:</p>

<p><img src="http://sciruby.com/images/gnuplotrb-gsoc2015/plots.jpg" alt="Plot example" style="width: 100%;"/></p>

<p>For code examples please see
 <a href="https://github.com/dilcom/gnuplotrb/blob/master/README.rdoc">the repository README</a>,
 <a href="https://github.com/dilcom/gnuplotrb/blob/master/notebooks/README.rdoc">notebooks</a>
 and <a href="https://github.com/dilcom/gnuplotrb/tree/master/examples">the examples folder</a>.</p>

<h3>Multiplot</h3>

<p><code>GnuplotRB::Multiplot</code> allows users to place several plots on a single layout and output
 them at once (e.g., to a PNG file).
 <a href="http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/multiplot_layout.ipynb">Multiplot notebook</a>.</p>

<p>Here is a multiplot example
 (taken from <a href="http://nbviewer.ipython.org/github/SciRuby/sciruby-notebooks/blob/master/Data%20Analysis/Analyzing%20baby%20names/Use%20Case%20-%20Daru%20for%20analyzing%20baby%20names%20data.ipynb">Sameer&#8217;s notebook</a>):</p>

<p><img src="http://sciruby.com/images/gnuplotrb-gsoc2015/multiplot.jpg" alt="Multiplot example" style="width: 80%; align: middle;"/></p>

<h3>Animated plots</h3>

<p>GnuplotRB may output any plot to gif file but <code>GnuplotRB::Animation</code> allows
 to make this gif animated. It takes several <code>Plot</code> or <code>Splot</code> objects just as
 multiplot does and outputs them one-by-one as frames of gif animation.
 <a href="http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/animated_plots.ipynb">Animation notebook</a>.</p>

<p><img src="http://sciruby.com/images/gnuplotrb-gsoc2015/trajectory.gif" alt="Trajectory example" style="width: 80%; align: middle;"/></p>

<h3>Fit</h3>

<p>Although the main GnuplotRB&#8217;s purpose is to provide you with swift, robust and
 easy-to-use plotting tool, it also offers a <code>Fit</code> module that contains several
 methods for fitting given data with a function. See examples in <a href="http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/fitting_data.ipynb">Fit notebook</a>.</p>

<h3>Integration with other SciRuby tools</h3>

<h4>Embedding plots into iRuby notebooks</h4>

<p>GnuplotRB plots may be embedded into iRuby notebooks as JPEG/PNG/SVG
 images, as ASCII art or GIF animations (<code>Animation</code> class). This functionality
 explained in a special <a href="http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/basic_usage.ipynb">iRuby notebook</a>.</p>

<h4>Using data from Daru containers</h4>

<p>To link GnuplotRB with other SciRuby tools I implemented plot
 creation from data given in Daru containers (<code>Daru::Dataframe</code> and <code>Daru::Vector</code>).
 One can use <code>daru</code> gem in order to work with statistical SciRuby gems
 and plotting with GnuplotRB. Notebooks with examples: <a href="http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/plotting_from_daru.ipynb">1</a>, <a href="http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/time_series_from_daru.ipynb">2</a>.</p>

<h3>Possible datasources for plots</h3>

<p>You can pass to Plot (or Splot or Dataset) constructor data in the following forms:</p>

<ul>
<li>String containing mathematical formula (e.g., <code>'sin(x)'</code>)</li>
<li>String containing name of file with data (e.g., <code>'points.data'</code>)</li>
<li>Some Ruby object responding to <code>#to_gnuplot_points</code>

<ul>
<li><code>Array</code></li>
<li><code>Daru::Dataframe</code></li>
<li><code>Daru::Vector</code></li>
</ul>
</li>
</ul>


<p>See examples in <a href="https://github.com/dilcom/gnuplotrb/blob/master/notebooks/README.rdoc#possible-datasources">notebooks</a>.</p>

<h2>Links</h2>

<ul>
<li><a href="https://github.com/dilcom/gnuplotrb/">Project repository</a></li>
<li><a href="https://rubygems.org/gems/gnuplotrb/">Gem page on Rubygems</a></li>
<li><a href="http://www.rubydoc.info/gems/gnuplotrb/0.3.1">Gem documentation on Rubydoc</a></li>
<li><a href="http://dilcom.github.io/gnuplotrb/">Blog of the project</a></li>
<li><a href="https://github.com/dilcom/gnuplotrb/tree/master/examples">Examples</a></li>
<li><a href="https://github.com/dilcom/gnuplotrb/blob/master/notebooks/README.rdoc">iRuby notebooks</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruby Wrappers for SymEngine, a C++ symbolic manipulation library]]></title>
    <link href="http://sciruby.com/blog/2015/08/17/ruby-wrappers-for-symengine/"/>
    <updated>2015-08-17T14:30:00+05:30</updated>
    <id>http://sciruby.com/blog/2015/08/17/ruby-wrappers-for-symengine</id>
    <content type="html"><![CDATA[<p>I am sure you have heard about <a href="http://www.wolframalpha.com/">Wolfram Alpha</a>. Some of you would have used its <a href="http://www.wolframalpha.com/examples/Math.html">Mathematics section</a> at some point of time to cross check your solution to a maths problem. If you haven&#8217;t, please do. A computer algebra system (CAS) does the same thing. Algebraic computation or symbolic computation are all used interchangeably. A CAS solves problems the same way a human does, but way more quickly and precisely. There is very less chance for an error, that we humans often make.</p>

<h2>Introduction</h2>

<p>My project was to write the Ruby extensions for the library <a href="https://github.com/sympy/symengine">SymEngine</a> and come up with a Ruby-ish interface, after which we can use the features of SymEngine from Ruby.</p>

<p><a href="https://github.com/sympy/symengine">SymEngine</a> is a library for symbolic computation in C++. You may ask, why SymEngine? There are other CASs that I know of. This question was indeed asked. At the beginning, the idea was to use ruby wrappers for <a href="http://www.sagemath.org/">sage</a> (a mathematics software system) which uses <a href="http://pynac.org/">Pynac</a>, an interface to <a href="http://www.ginac.de/">GiNaC</a> (another CAS). As it turns out from the benchmarks, SymEngine is much faster than Pynac. What about directly wrapping GiNaC? SymEngine is also a bit faster than GiNaC.</p>

<p>The motivation for <a href="https://github.com/sympy/symengine">SymEngine</a> itself is to develop it once in C++ and then use it from other languages rather than doing the same thing all over again for each language that it is required in. In particular, a long term goal is to make Sage as well as SymPy use it by default, thus unifying the Python CAS communities. The goal of implementing the Ruby wrappers is to provide a CAS for the Ruby community.</p>

<h3>How will this be useful?</h3>

<p>There are times when we might need a symbolic computation library. Here is an incomplete list of some of the situations:</p>

<ul>
<li>We need to do some algebra to get systems of equations in suitable form for numerical computation.</li>
<li>We need to make substitutions for some variables and don’t want to risk a math error by hand. There might be times when we want to partially simplify an expression by substituting only a few of its variables.</li>
<li>We have a situation where we need to find the optimum number of something to maximise our profits, and the mathematical model devised is just too complicated to solve by hand.</li>
<li>We need to perform non-trivial derivatives or integrals.</li>
<li>We are trying to understand the domain of a new function.</li>
<li>Most root finding algorithms search for a single root, whereas often there are more than one.</li>
<li>We need to solve a linear system or manipulate a symbolic matrix exactly.</li>
<li>We need to manipulate exact expressions and solutions, as opposed to approximate ones using a numerical method.</li>
</ul>


<p>With that said, a symbolic manipulation library is indispensable for scientists and students. Ruby has gained a great deal of popularity over the years, and a symbolic manipulation library gem  like this project in Ruby might prove to be the foundation for a computer algebra system in Ruby. With many efforts like these, Ruby might become the first choice for academicians given how easy it is to code your logic in Ruby.</p>

<h2>How to install the gem?</h2>

<p>To install, please follow the <a href="https://github.com/sympy/symengine/blob/master/symengine/ruby/README.md">compile instructions given in the README</a>. After you are done, I would suggest to test the extensions. To run the test suite execute <code>rspec spec</code> on the command line, from the <code>symengine/ruby</code> dir.</p>

<p>The gem is still in alpha release. Please help us out by reporting any issues in <a href="https://github.com/sympy/symengine/issues">the repo issue tracker</a>.</p>

<h2>What can I do with the gem?</h2>

<p>Currently, the following features are available in the gem:
- Construct expressions out of variables (mathematical).
- Simplify the expressions.
- Carry out arithmetic operations like <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, <code>**</code> with the variables and expressions.
- Extract arguments or variables from an expression.
- Differentiate an expression with respect to another.
- Substitute variables with other expressions.</p>

<p>Features that will soon be ported to the SymEngine gem
- Functions, including trigonometric, hyperbolic and some special functions.
- Matrices, and their operations.
- Basic number-theoretic functions.</p>

<p>I have developed a <a href="https://github.com/sympy/symengine/tree/master/symengine/ruby/notebooks">few IRuby notebooks</a> that demonstrate the use of the new SymEngine module in ruby.</p>

<p>Below is an example taken from the notebooks.</p>

<hr />

<h2>Using the SymEngine Gem</h2>

<p>SymEngine is a module in the extensions, and the classes are a part of it. So first you fire up the interpreter or an IRuby notebook and load the file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;symengine&#39;</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">true</span>
</span></code></pre></td></tr></table></div></figure>


<p>Go ahead and try a function:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">SymEngine</span><span class="o">.</span><span class="n">ascii_art</span>
</span><span class='line'><span class="o">=&gt;</span>   <span class="n">_____</span>           <span class="n">_____</span>         <span class="n">_</span>
</span><span class='line'>    <span class="o">|</span>   <span class="n">__</span><span class="o">|</span><span class="n">_</span> <span class="n">_</span> <span class="n">_____</span><span class="o">|</span>   <span class="n">__</span><span class="o">|</span><span class="n">___</span> <span class="n">___</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">___</span> <span class="n">___</span>
</span><span class='line'>    <span class="o">|</span><span class="n">__</span>   <span class="o">|</span> <span class="o">|</span> <span class="o">|</span>     <span class="o">|</span>   <span class="n">__</span><span class="o">|</span>   <span class="o">|</span> <span class="o">.</span> <span class="o">|</span> <span class="o">|</span>   <span class="o">|</span> <span class="o">-</span><span class="n">_</span><span class="o">|</span>
</span><span class='line'>    <span class="o">|</span><span class="n">_____</span><span class="o">|</span><span class="n">_</span>  <span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">_____</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">_</span>  <span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="n">___</span><span class="o">|</span>
</span><span class='line'>          <span class="o">|</span><span class="n">___</span><span class="o">|</span>               <span class="o">|</span><span class="n">___</span><span class="o">|</span>
</span></code></pre></td></tr></table></div></figure>


<p>or create a variable:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">basic</span> <span class="o">=</span> <span class="no">SymEngine</span><span class="o">::</span><span class="no">Basic</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;SymEngine::Basic:0x00000001e95290&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This shows that we have successfully loaded the module.</p>

<h3>SymEngine::Symbol</h3>

<p>Just like there are variables like x, y, and z in a mathematical expression or equation, we have <code>SymEngine::Symbol</code> in SymEngine to represent them. To use a variable, first we need to make a <code>SymEngine::Symbol</code> object with the string we are going to represent the variable with.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">puts</span> <span class="n">x</span> <span class="o">=</span> <span class="no">SymEngine</span><span class="o">::</span><span class="no">Symbol</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;x&quot;</span><span class="p">)</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">y</span> <span class="o">=</span> <span class="no">SymEngine</span><span class="o">::</span><span class="no">Symbol</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;y&quot;</span><span class="p">)</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">z</span> <span class="o">=</span> <span class="no">SymEngine</span><span class="o">::</span><span class="no">Symbol</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;z&quot;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">x</span>
</span><span class='line'><span class="n">y</span>
</span><span class='line'><span class="n">z</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then we can construct expressions out of them:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">e</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="n">y</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">**</span><span class="n">y</span><span class="o">/</span><span class="n">z</span><span class="p">)</span>
</span><span class='line'><span class="n">e</span><span class="o">.</span><span class="n">to_s</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;x**y*(x - y)/z&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>In SymEngine, every object is an instance of Basic or its subclasses. So, even an instance of <code>SymEngine::Symbol</code> is a Basic object.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">x</span><span class="o">.</span><span class="n">class</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="no">SymEngine</span><span class="o">::</span><span class="no">Symbol</span>
</span><span class='line'>
</span><span class='line'><span class="n">x</span><span class="o">.</span><span class="n">is_a?</span> <span class="no">SymEngine</span><span class="o">::</span><span class="no">Basic</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">true</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now that we have an expression, we would like to see it&#8217;s expanded form using <code>#expand</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">f</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">expand</span><span class="p">()</span>
</span><span class='line'><span class="n">f</span><span class="o">.</span><span class="n">to_s</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;x**(1 + y)/z - x**y*y/z&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Or check if two expressions are same:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">f</span> <span class="o">==</span> <span class="o">-</span> <span class="p">(</span><span class="n">x</span><span class="o">**</span><span class="n">y</span><span class="o">*</span><span class="n">y</span><span class="o">/</span><span class="n">z</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="n">x</span><span class="o">**</span><span class="n">y</span><span class="o">*</span><span class="n">x</span><span class="o">/</span><span class="n">z</span><span class="p">)</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">true</span>
</span></code></pre></td></tr></table></div></figure>


<p>But <code>e</code> and <code>f</code> are not equal since they are only mathematically equal, not structurally:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">e</span> <span class="o">==</span> <span class="n">f</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="kp">false</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let us suppose you want to know <strong>what variables/symbols your expression has</strong>. You can do that with the <code>#free_symbols</code> method, which returns a set of the symbols that are in the expression.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">f</span><span class="o">.</span><span class="n">free_symbols</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="c1">#&lt;Set: {#&lt;SymEngine::Basic:0x00000001f0ca70&gt;, #&lt;SymEngine::Basic:0x00000001f0ca48&gt;, #&lt;SymEngine::Basic:0x00000001f0ca20&gt;}&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let us use <code>#map</code> method to see the elements of the <code>Set</code>.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">f</span><span class="o">.</span><span class="n">free_symbols</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span><span class="o">.</span><span class="n">to_s</span> <span class="p">}</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span><span class="s2">&quot;x&quot;</span><span class="p">,</span> <span class="s2">&quot;y&quot;</span><span class="p">,</span> <span class="s2">&quot;z&quot;</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>#args</code> returns the terms of the expression,:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span><span class="o">.</span><span class="n">to_s</span> <span class="p">}</span>
</span><span class='line'><span class="o">[</span><span class="s2">&quot;-x**y*y/z&quot;</span><span class="p">,</span> <span class="s2">&quot;x**(1 + y)/z&quot;</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>or if it is a single term it breaks down the elements:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">f</span><span class="o">.</span><span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">].</span><span class="n">args</span><span class="o">.</span><span class="n">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">k</span><span class="o">|</span> <span class="n">k</span><span class="o">.</span><span class="n">to_s</span> <span class="p">}</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="o">[</span><span class="s2">&quot;-1&quot;</span><span class="p">,</span> <span class="s2">&quot;x**y&quot;</span><span class="p">,</span> <span class="s2">&quot;y&quot;</span><span class="p">,</span> <span class="s2">&quot;z**(-1)&quot;</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<h3>SymEngine::Integer</h3>

<p>You can make objects of class <code>SymEngine::Integer</code>. It&#8217;s like regular <code>Integer</code> in ruby kernel, except it can do all the operations a <code>Basic</code> object can &mdash; such as arithmetic operations, etc.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">a</span> <span class="o">=</span> <span class="no">SymEngine</span><span class="o">::</span><span class="nb">Integer</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span>
</span><span class='line'><span class="n">b</span> <span class="o">=</span> <span class="no">SymEngine</span><span class="o">::</span><span class="nb">Integer</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">64</span><span class="p">)</span>
</span><span class='line'><span class="n">a</span><span class="o">**</span><span class="n">b</span>
</span><span class='line'>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">1168422057627266461843148138873451659428421700563161428957815831003136</span>
</span></code></pre></td></tr></table></div></figure>


<p>Additionally, it can support numbers of arbitrarily large length.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="p">(</span><span class="n">a</span><span class="o">**</span><span class="n">x</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;12**x&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>SymEngine::Rational</h3>

<p>You can also make objects of class <code>SymEngine::Rational</code> which is the SymEngine counterpart for <code>Rationals</code> in Ruby.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">c</span> <span class="o">=</span> <span class="no">Rational</span><span class="p">(</span><span class="s1">&#39;2/3&#39;</span><span class="p">)</span>
</span><span class='line'><span class="n">d</span> <span class="o">=</span> <span class="no">SymEngine</span><span class="o">::</span><span class="no">Rational</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="o">=&gt;</span> <span class="mi">2</span><span class="o">/</span><span class="mi">3</span>
</span></code></pre></td></tr></table></div></figure>


<p>Like any other <code>Basic</code> object arithmetic operations can be done on this rational type too.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="p">(</span><span class="n">a</span><span class="o">-</span><span class="n">d</span><span class="p">)</span><span class="o">.</span><span class="n">to_s</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;34/3&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<hr />

<p>You <strong>need not create</strong> an instance of <code>SymEngine::Integer</code> or <code>SymEngine::Rational</code>, every time you want to use them in an expression that uses many <code>Integer</code>s. Let us say you already have <code>Integer</code>/<code>Rational</code> object. Even then you can use them without having to create a new <code>SymEngine</code> object.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">k</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="o">/</span> <span class="p">(</span><span class="n">x</span> <span class="o">*</span> <span class="n">y</span><span class="p">)</span> <span class="o">-</span> <span class="n">x</span> <span class="o">*</span> <span class="n">y</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">c</span> <span class="o">+</span> <span class="n">x</span> <span class="o">*</span> <span class="n">y</span><span class="p">)</span> <span class="c1"># c is a Rational object, not SymEngine::Rational</span>
</span><span class='line'><span class="n">k</span><span class="o">.</span><span class="n">to_s</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;(2/3 + x*y)*(2 + 1/(x*y) - x*y)&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>As you can see, ruby kernel <code>Integer</code>s and <code>Rational</code>s interoperate seamlessly with the <code>SymEngine</code> objects.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">k</span><span class="o">.</span><span class="n">expand</span><span class="o">.</span><span class="n">to_s</span>
</span><span class='line'><span class="o">=&gt;</span> <span class="s2">&quot;7/3 + (2/3)*1/(x*y) + (4/3)*x*y - x**2*y**2&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<hr />

<h2>What I learned</h2>

<p>In the rest of the post, I would like to summarise my work and what I learned as a participant of <a href="https://www.google-melange.com/gsoc/homepage/google/gsoc2015">Google Summer of Code 2015</a>.</p>

<h2>Pre-midterm Evaluations</h2>

<p>I am a newbie when it comes to Ruby, and it took me a while to setup the gem and configure files for the building of extensions.</p>

<h3>The struggle between shared, static and dynamic libraries</h3>

<p>I faced a lot of problem in the early stages, when I was trying to build the extensions. <a href="https://github.com/certik">Ondrej</a>, my mentor, and <a href="https://github.com/isuruf">Isuru</a>, a fellow GSoC student, helped me a lot. There were many C flags that were being reported as missing. Some flags <code>cmake</code> added by default but <code>extconf.rb</code> didn&#8217;t, the same one that was required to be added to build it as a shared library. I am still confused about the details, some of which are <a href="http://abinashmeher999.github.io/2015/05/29/Building-the-wrappers/">explored in greater detail in my personal blog</a>. Finally, the library had to be built as a dynamic one. The problem of missing C flags was resolved later by hooking the process to <code>cmake</code> rather than <code>mkmf</code>.</p>

<h3>Load Errors and problems in linking</h3>

<p>Many <a href="http://abinashmeher999.github.io/2015/06/12/The-Load-Error/"><code>LoadError</code>s</a> popped up, but were eventually solved. <a href="https://github.com/dilcom/">Ivan</a> helped a lot in debugging the errors. In the end, it turned out to be a simple file missing in the gemspec, that was not being installed.</p>

<h3>Reconfiguring building</h3>

<p>One of our aims during developing this was to get rid of unessential dependencies. The ones we already had the tools for. Like later the file <code>extconf.rb</code>, that is used to generate Makefile for the extension was removed, because that could also be done by <code>cmake</code>. Flags were added to <code>cmake</code> for building the Ruby extensions, like the flag <code>-DWITH_RUBY=yes</code>. The <code>Makefile</code> then generates the library <code>symengine.so</code> in the directory <code>lib/symengine</code>.Along with <code>extconf.rb</code>, the file <code>extconf.h</code> was also gone. Along these lines, the dependency on <code>rake</code> was also removed, and with that the <code>Rakefile</code>. Any task automation will most probably be done in python. So, the <code>Rake::ExtensionTask</code> was done by <code>cmake</code> and the <code>Rake::GemPackageTask</code> was replaced by the manual method of <code>gem build symengine.gemspec</code> and <code>gem install symengine-0.0.0.gem</code></p>

<h3>Travis setup</h3>

<p>Not many projects have travis-ci setup for multiple languages. Not even the tutorials had clearly mentioned about setting up for multiple languages. But I did know about one of them, which is Shogun, the machine-learning toolbox. I referred to their <code>.travis.yml</code> and setup it up. If something like this wouldn&#8217;t have worked the plan was to manually install the required version of ruby and then execute the shell commands.</p>

<h3>Making a basic object</h3>

<p>Finally, I was able to successfully build the extensions, link the extensions with the SymEngine library, load the ruby-extension library in the interpreter and successfully instantiate an object of type <code>Basic</code>.</p>

<h3>Inheritance and Symbols</h3>

<p>At this time, the way inheritance works(like the sequence of formation and destruction of objects of a class that had a superclass) with the Ruby C API, was confusing for all of us. I designed an <a href="http://abinashmeher999.github.io/2015/06/26/the-symbol-class/#inheritance-in-ruby-c-api">experiment</a>
to check what was actually happening. That cleared things out, and made the it easier to wrap things from now on. I also wrapped the <code>Symbol</code> class during the course.</p>

<h2>Post-midterm Evaluations</h2>

<h3>Redesign of the C interface</h3>

<p>We had to design an ugly function to wrap vector in C. That led us to redesign the C interface. This approach had no reinterpret casting that was being done earlier. Each data structure had a type that was determined at compile time. For C, it was an opaque structure, while for C++ the opaque structure declared in the shared header file was implemented in the source file that had C++ data types. This <a href="http://abinashmeher999.github.io/2015/07/03/improving-the-c-interface/">blog post</a> explains it further.</p>

<h3>Integer and Rational</h3>

<p>While trying to port the SymEngine classes, <code>Integer</code> and <code>Rational</code>, I had to port many methods in <code>Basic</code> before that. I also replicated the <code>rake</code> tasks in NMatrix, for detection of memory leaks, in form of bash scripts.</p>

<h3>Common enumeration</h3>

<p>Since all objects in the Ruby C API are of the type <code>CBasic</code>, we needed a function that would give us the typename during the runtime for the corresponding objects to be wrapped in ruby, as an object of the correct <code>Class</code> in ruby. Since, this was achieved with <code>enum</code> in C++, the same thing could be done in C too, with all the classes written manually again. But there was no guarantee for this to be consistent, if ever the features required to be wrapped for a new language, and also manually adding the class in all the enum list everytime a new class is added was prone to errors. So, to make this DRY, we automated this by sharing the list of enums. More details for the implementation can be found <a href="http://abinashmeher999.github.io/2015/07/17/common-enumeration-in-c-and-c++/">here</a>.</p>

<h3>Class coercion and interoperability</h3>

<p>To support interoperability with the builtin ruby types, I had to overload the methods in builtin classes earlier(this was not continued). Overriding all the existing binary operations for a ruby class to support SymEngine types, violated the open/closed principle. There was indeed another way, which is <em>&#8216;Class Coercion&#8217;</em>. It was suggested by <a href="https://github.com/isuruf/">Isuru</a>. After that, SymEngine types could seamlessly interoperate between the ruby types.</p>

<h3>Arithmetic operations</h3>

<p>After this, all the arithmetic operations had been successfully ported. Each <code>Basic</code> object can now perform arithmetic operations with other <code>Basic</code> object(sometimes even ruby objects like <code>Integer</code>). The test file in python, that had all the corresponding test cases was ported to its RSpec counterpart.</p>

<h3>Substitutions</h3>

<p>Recently I completed porting the substitutions module to the extensions(<code>#subs</code>). This feature has added a lot of convenience as now you can substitute a <code>SymEngine::Symbol</code> with some other value in an expression and then <code>#expand</code> to get the result.</p>

<h3>Trigonometric functions</h3>

<p>Currently, I am working on porting the trigonometric functions in SymEngine to the extensions. This would first require to wrap the <code>Function</code> class and then the <code>TrigFunction</code> class in SymEngine.</p>

<h3>Integration of other Ruby gems</h3>

<p>I also have plans to integrate the ruby bindings for <code>gmp</code>, <code>mpfr</code> and <code>mpc</code> libraries, that are already available as gems, with ruby bindings for our library. I have created an issue <a href="https://github.com/sympy/symengine/issues/490">here</a>. Feel free to drop any suggestions.</p>

<hr />

<p>There is much scope for improvement in both the projects. For SymEngine, to support more features like polynomials and series-expansion in the near future, and improving the user interface and the exception handling for the extensions. In short, making the extensions more ruby-ish.</p>

<p>I am grateful to my mentor, <a href="https://github.com/certik">Mr. Ondřej Čertík</a>, the <a href="http://sciruby.com/">Ruby Science Foundation</a> and the <a href="http://www.sympy.org/en/index.html">SymPy Organisation</a> for the opportunity that they gave me and guiding me through the project, and my team-mates for helping me with the issues. I hope more people will contribute to the project and together we will give a nice symbolic manipulation gem to the Ruby community.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Summary of work on daru this summer for GSOC 2015]]></title>
    <link href="http://sciruby.com/blog/2015/08/16/summary-of-work-on-daru-this-summer-for-gsoc-2015/"/>
    <updated>2015-08-16T23:53:00+05:30</updated>
    <id>http://sciruby.com/blog/2015/08/16/summary-of-work-on-daru-this-summer-for-gsoc-2015</id>
    <content type="html"><![CDATA[<p>Over this summer as a part of <a href="www.google-melange.com">Google Summer of Code 2015</a>, <a href="www.github.com/v0dro/daru/">daru</a> received a lot of upgrades and new features which have it made a pretty robust tool for data analysis in pure Ruby. Of course, a lot of work still remains for bringing daru at par with the other data analysis solutions on offer today, but I feel the work done this summer has put daru on that path.</p>

<p>The new features led to the inclusion of daru in many of SciRuby&#8217;s gems, which use daru&#8217;s data storage, access and indexing features for storing and carrying around data. <a href="https://github.com/SciRuby/statsample">Statsample</a>, <a href="https://github.com/SciRuby/statsample-glm">statsample-glm</a>, <a href="https://github.com/SciRuby/statsample-timeseries">statsample-timeseries</a>, <a href="https://github.com/SciRuby/statsample-bivariate-extension">statsample-bivariate-extensions</a> are all now compatible with daru and use <code>Daru::Vector</code> and <code>Daru::DataFrame</code> as their primary data structures. I also overhauled Daru&#8217;s <a href="http://nbviewer.ipython.org/github/SciRuby/sciruby-notebooks/blob/master/Visualization/Visualizing%20data%20with%20daru%20DataFrame.ipynb">plotting functionality</a>, that interfaced with <a href="https://github.com/domitry/nyaplot">nyaplot</a> for creating interactive plots directly from the data.</p>

<p>Also, new gems developed by other GSOC students, notably <a href="https://github.com/dilcom/gnuplotrb">Ivan&#8217;s GnuplotRB gem</a> and <a href="https://github.com/agisga/mixed_models">Alexej&#8217;s mixed_models gem</a> both now accept data from daru data structures. Do see their repo pages for seeing interesting ways of using daru.</p>

<p>The work on daru is also proving to be quite useful for other people, which led to a talk/presentation at <a href="http://www.deccanrubyconf.org/">DeccanRubyConf 2015</a>, which is one of the three major Ruby conferences in India. You can see the slides and notebooks presented at the talk <a href="https://github.com/v0dro/talks/tree/master/DeccanRubyConf15">here</a>. Given the current interest in data analysis and the need for a viable solution in Ruby, I plan to take daru much further. Keep watching the repo for interesting updates :)</p>

<p>In the rest of this post I&#8217;ll elaborate on all the work done this summer.</p>

<h2>Pre-mid term submissions</h2>

<p>Daru as a gem before GSOC was not exactly user friendly. There were many cases, particularly the iterators, that required some thinking before anybody used them. This is against the design philosophy of daru, or even Ruby general, where surprising programmers with ubiqtuos constructs is usually frowned down upon by the community. So the first thing that I did mainly concerned overhauling the daru&#8217;s many iterators for both <code>Vector</code> and <code>DataFrame</code>.</p>

<p>For example, the <code>#map</code> iterator from <code>Enumerable</code> returns an <code>Array</code> no matter object you call it on. This was not the case before, where <code>#map</code> would a <code>Daru::Vector</code> or <code>Daru::DataFrame</code>. This behaviour was changed, and now <code>#map</code> returns an <code>Array</code>. If you want a <code>Vector</code> or a <code>DataFrame</code> of the modified values, you should call <code>#recode</code> on <code>Vector</code> or <code>DataFrame</code>.</p>

<p>Each of these iterators also accepts an optional argument, <code>:row</code> or <code>:vector</code>, which will define the axis over which iteration is supposed to be carried out. So now there are the <code>#each</code>, <code>#map</code>, <code>#map!</code>, <code>#recode</code>, <code>#recode!</code>, <code>#collect</code>, <code>#collect_matrix</code>, <code>#all?</code>, <code>#any?</code>, <code>#keep_vector_if</code> and <code>#keep_row_if</code>. To iterate over elements along with their respective indexes (or labels), you can likewise use <code>#each_row_with_index</code>, <code>#each_vector_with_index</code>, <code>#map_rows_with_index</code>, <code>#map_vector_with_index</code>, <code>#collect_rows_with_index</code>, <code>#collect_vector_with_index</code> or <code>#each_index</code>. I urge you to go over the docs of each of these methods to utilize the full power of daru.</p>

<p>Apart from the improvements to iterators there was also quite a bit of refactoring involved for many methods (courtesy <a href="https://github.com/agisga">Alexej</a>). The refactoring of certain core methods has made daru much faster than previous versions.</p>

<p>The next (major) thing to do was making daru compatible with Statsample. This was very essential since statsample is very important tool for statistics in Ruby and it was using its own <code>Vector</code> and <code>Dataset</code> classes, which weren&#8217;t very robust as computation tools and very difficult to use when it came to cleaning or munging data. So I replaced statsample&#8217;s Vector and Dataset clases with <code>Daru::Vector</code> and <code>Daru::DataFrame</code>. It involved a significant amount of work on both statsample and daru &mdash; Statsample because many constructs had to be changed to make them compatible with daru, and daru because there was a lot of essential functionality in these classes that had to be ported to daru.</p>

<p>Porting code from statsample to daru improved daru significantly. There were a whole of statistics methods in statsample that were imported into daru and you can now use all them from daru. Statsample also works well with <a href="https://github.com/clbustos/rubyvis">rubyvis</a>, a great tool for visualization. <a href="https://github.com/SciRuby/statsample#visualizations">You can now do that with daru as well</a>.</p>

<p>Many new methods for reading and writing data to and from files were also added to daru. You can now read and write data to and from CSV, Excel, plain text files or even SQL databases.</p>

<p>In effect, daru is now completely compatible with Statsample (and all the other Statsample extensions). You can use daru data structures for storing data and pass them to statsample for performing computations. The biggest advantage of this approach is that the analysed data can be passed around to other scientific Ruby libraries (some of which listed above) that use daru as well. Since daru offers in-built functions to better &#8216;see&#8217; your data, better visualization is possible.</p>

<p>See these <a href="https://github.com/v0dro/daru#blog-posts">blogs</a> and <a href="https://github.com/v0dro/daru#notebooks">notebooks</a> for a complete overview of daru&#8217;s new features.</p>

<p>Also see the <a href="https://github.com/SciRuby/statsample#notebooks">notebooks in the statsample README</a> for using daru with statsample.</p>

<h2>Post-mid term submissions</h2>

<p>Most of time post the mid term submissions was spent in implementing the time series functions for daru.</p>

<p>I implemented a new index, the DateTimeIndex, which can used for indexing data on time stamps. It enables users to query data based on time stamps. Time stamps can either be specified with precise Ruby DateTime objects or can be specified as strings, which will lead to retrival of all the data falling under that time. For example specifying &#8216;2012&#8217; returns all data that falls in the year 2012. See detailed usage of <code>DateTimeIndex</code> and <code>DateTime</code> in conjunction with other daru constructs <a href="https://github.com/v0dro/daru/blob/master/README.md">in the daru README</a>.</p>

<p>An essential utility in implementing <code>DateTimeIndex</code> was <code>DateOffset</code>, which is a new set of classes that offsets dates based on certain rules or business logic. It can advance or lag a Ruby <code>DateTime</code> to the nearest day, or any day of the week, or the end or beginning of the month, etc. <code>DateOffset</code> is an essential part of <code>DateTimeIndex</code> and can also be used as a stand-alone utility for advancing/lagging <code>DateTime</code> objects. <a href="http://v0dro.github.io/blog/2015/07/27/date-offsets-in-daru/">This blog post</a> elaborates more on the nuances of <code>DateOffset</code> and its usage.</p>

<p>The last thing done during the post mid term was complete compatibility with <a href="https://github.com/AnkurGel">Ankur Goel</a>&#8217;s <a href="https://github.com/SciRuby/statsample-timeseries">statsample-timeseries</a>, which was created by  during GSOC 2013. Statsample-timeseries is a comprehensive suite offering various functions for statistical analysis of time sries data. It now works with daru containers and can be used for statistical analysis of data indexed on <code>Daru::DateTimeIndex</code>. See some use cases <a href="https://github.com/SciRuby/statsample-timeseries/blob/master/README.rdoc">in the README</a>.</p>

<p>I&#8217;d like to conclude by thanking all the people directly and indirectly involved in making this project a success - My mentor <a href="https://github.com/agarie">Carlos</a> for his help and support throughout the summer, <a href="https://github.com/dilcom">Ivan</a>, <a href="https://github.com/agisga">Alexej</a> and <a href="https://github.com/wlevine">Will</a> for their support and feedback in various stages of developing daru. Also a big thank you to all the <a href="https://github.com/orgs/SciRuby/teams">SciRuby maintainers</a> for making this happen!</p>
]]></content>
  </entry>
  
</feed>
